/* *****************************************************************************
     JavaScript Advanced Calendar Script (JACS) - Cross-Browser pop-up calendar.

     Copyright (C) 2007-2008  Anthony Garrett

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, it is available at
     the GNU web site (http://www.gnu.org/) or by writing to the
     Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
     Boston, MA  02110-1301  USA

*///*****************************************************************************
/*
   Contact:   Sorry, I can't offer support for this but if you find a problem
              (or just want to tell me how useful you find it), please send
              me an email at jacsFeedback@tarrget.info (Note the two Rs in
              tarrget).  I will try to fix problems quickly but this is a
              spare time thing for me.

   Credits:   I wrote this based on my Simple Calendar Widget script which
              I wrote from scratch myself but I couldn't have done either
              without the superb "JavaScript The Definitive Guide" by David
              Flanagan (Pub. O'Reilly ISBN 0-596-00048-0) and Peter-Paul Koch's
              (PPK) brilliant Quirksmode site.

   Link back: Please give me credit and link back to my page if you can.  To
              ensure that search engines give my page a higher ranking you can
              add the following HTML to any indexed page on your web site:

              <A HREF="http://www.tarrget.info/calendar/jacs.htm">
                JavaScript Advanced Calendar Script (JACS) by Anthony Garrett
              </A>

              Your root directory of the web site should also contain an empty
              file called "jacsblank.html". For a full explanation see
              http://www.tarrget.info/calendar/IEnightmare.html.

   Features:  Easily customised (output date format, colours, language,
                                 year range and week start day)
              Accepts a date as input (see comments below for formats).
              Allows multiple calendars on a page and static calendar displays.

              Cross-browser code tested against;
                    Internet Explorer 6.0.28+    Mozilla  1.7.1
                    Opera             7.52+      Firefox  0.9.1+
                    Konqueror         4.0.1      Safari   3 (Beta for Windows)

   How to add the Calendar to your page:
              This script needs to be defined for your page so add the following
              line;
                    <script type='text/JavaScript' src='jacs.js'></script>

   How to use the Calendar once it is defined for your page:

        Dynamic calendar:

              Simply choose an event to trigger the calendar (like an onclick or an onmouseover)
              and an element to work on (for the calendar to take its initial date from and write
              its output date to) then write it like this;

                    onclick="JACS.show(document.getElementById('myElement'),event);"
                or
                    onfocus="JACS.show(this,event);"

              NOTE: If you wish to use the calendar with an Anchor tag, do not use the
                    href="javascript:JACS.show(...)" syntax.

                    Instead you should use the following;

                    <a href="#" onclick="JACS.show(<<element>>,event);return false;">
                        <<your text>>
                    </a>

              If you are using a text node then specify the text's parent node in the
              function call. The date should be the only text under that node;

                    <p onclick="JACS.show(this,event);"><<date>></p>

        Static calendar:

                    JACS.show(<<element>><<,optional calendar ID>><<,optional disabled days>>);

              A static calendar appears on screen when the page loads, cannot be dragged and
              remains on screen after it has been used to select a date. It returns the date
              into the value of a defined element (e.g. an INPUT element) but, of course,
              that can be hidden.

        Calendar with selected days:

              You can select days of the week by adding arguments to the
              call to JACS.show. These selected days can be the only ones
              enabled or the only ones disabled depending on the setting of
              the attribute valuesEnabled (see below). The values should be
              Sunday = 0 through to Saturday = 6. The parameters can be a
              series of single values or an array holding those values. A call
              to JACS.show with Friday and Monday selected could look something
              like this;

                        JACS.show(<<element>>,event,5,1);
              or this;
                        var myArray = [5,1];
                        JACS.show(<<element>>,event,myArray);

        Named calendar:

                    JACS.show(<<element>>,event<<,calendar ID>>);

              'jacs' is the default ID of the calendar but you can assign any ID
              you want.  You can call one name as many times as you like,
              but as it is one object, it can only appear on screen in one location
              at a time.  If you want more than that then you must give different IDs.

              [Note: in the above paragraph I use "name" and "id" interchangeably, not
                     in the sense of HTML tag attributes "name" and "id". ]

        No event? No problem!

              Normally the calendar will be triggered by an event but if you wish to
              control it in code and the event is not available to you, simply pass
              an element as the second parameter;

              E.G.  JACS.show(<<target element>>,<<source element>>);
                    as in: JACS.show(this,this);

        Calendar with post-processing:

              The following technique runs a function each time a dynamic calendar
              closes or a date is selected from a static calendar:

                    JACS.show(<<Dynamic or Static calendar argument list>>);
                    JACS.next(<<optional calendar ID,>><<function>><<,arguments>>);

              Where <<function>> is a function defined on the calling page
              and <<arguments>> is the list of arguments being passed to that
              function.

              The calendar ID defaults to 'jacs', if you are using a different
              calendar object (See calendar naming above), you must give its
              ID as the first argument.

              NOTES: These two calls are expected in this order (i.e. show before
                     next) because JACS.next expects the calendar object to exist.

                     If JACS.make has not been called for the object and JACS.show
                     is called after JACS.next then the calendar object may not
                     exist (if the object has not been created earlier in the
                     users path through the page) so a JavaScript error would
                     be generated.

              Every function that is triggered using JACS.next() acquires an
              attribute JACSid. This attribute holds the value of the
              calendar ID that JACS.next() has been called for. So, your
              function has access to all of the calendar instance's attributes.
              These include;
                dateReturned  Boolean TRUE if the calendar has been closed by
                              selection of a date, otherwise FALSE), and
                outputDate    The user-selected date in JavaScript date format.

                    E.G. document.getElementById(<<function>>.JACSid).dateReturned

        Disabling or enabling dates or date ranges;

              Setting enabled or disabled date ranges for a calendar object is
              achieved by setting the dates array attribute of the calendar object
              (see more information below).

              By default the calendar object is only created when it is first
              needed for display so you should make sure that it is explicitly
              created using;

                    JACS.make(<<calendar id>><<,dynamic (boolean, default TRUE)>>);

        Combining the techniques:

              A fully defined call to JACS.show, including all optional parameters
              should send parameters in the following order;

                            I/O      Trigger  Calendar  Selected
                            Element  Event    ID        days
              Dynamic         0        1        2         2/3
              Static          0                 1         1/2
              Type          Object   Object   String    Number(s)
              Required      Yes      Yes      No        No
              Default       None     None     'jacs'    None

              NOTE: The Trigger Event is ONLY relevant for dynamic calendars
                    and must be omitted for static calendars.

              Dynamic e.g.  JACS.show(document.getElementById('myElement1'),
                                      event,'jacs',0,1,2,3,4,5,6);

              Static  e.g.  JACS.show(document.getElementById('myElement2'),
                                           'myCal',0,6);

              A single calendar instance must not be called with both Dynamic
              and Static parameters (It is only one structure within the page
              so it cannot remain visible in one location while it is displayed
              in another).

----------------------------------------------------------------------------------
   See http://www.tarrget.info/calendar/scw.htm for a full version history
   up to version 3.60 and
       http://www.tarrget.info/calendar/jacs.htm for versions to date.

   Version   Date        By               Description
   =======   ====        ===============  ===========
     1.30    2008-05-05  Anthony Garrett  Added optional auto-positioning of the
                                           calendar when its normal position would
                                           go off the visible area.
                                           Thanks to Chandramouli Iyer for this
                                           suggestion.
                                          Added an optional "Clear" button for
                                           use when handling a read-only text
                                           input element. Thanks to Sanjay Gangwal
                                           for his suggestion.

     1.21    2008-04-11  Anthony Garrett  Corrected the input month name parsing
                                            so that it set the calendar to the
                                            right month when long month names used.
                                            Thanks to Ben Diamand for this bug report.

     1.20    2008-04-10  Anthony Garrett  Added attribute to allow calendar to
                                           appear in "display" mode only (i.e.
                                           dates not selectable.

                                          Added the option to highlight specified
                                           dates and date ranges.

                                          Thanks to Ben Diamand for both
                                           suggestions.

     1.11    2008-02-24  Anthony Garrett  Trapped calls to script with only a
                                           NAME attribute is set for the target
                                           element when the script really requires
                                           an ID attribute.  This is the most
                                           frequent mistake reported to me.

     1.10    2008-01-14  Anthony Garrett  Restored the ability to use an element
                                           as the second parameter when opening a
                                           dynamic calendar while retaining the
                                           option of passing an event. Thanks to
                                           Thierry Blind and Sergey Snovsky for
                                           the feedback.

                                          Added a calendar attribute that holds the
                                           returned date. This simplifies use of
                                           the calendar within JavaScript. Thanks
                                           to Juha Valvanne for the query that
                                           led to this enhancement.

                                          Fixed bug in the handling of focus events
                                           that caused calendar to fail to appear.
                                           Thanks to Steve Davis for reporting the
                                           problem.

     1.00    2007-09-21  Anthony Garrett  Fixed JACS.next parameters - thanks to
                                           Rogier Lankhorst for the feedback, also
                                           refined JACS.next processing.

                                          Updated the event trapping to make it
                                           less intrusive on the page body.  NOTE:
                                           This requires that a dynamic calendar's
                                           second parameter should be the calling
                                           event (not the calling object as in
                                           previous versions).  Thanks to Steve
                                           Davis for the bug report that led to
                                           this change.

                                          Replaced the date input sequence user
                                           configuration setting with parsing the
                                           sequence from the full format. New users
                                           are often confused by the sequence and
                                           in practice (to allow the calendar's date
                                           output to be used for input) the sequence
                                           must always match the full format element
                                           order.

                                          Fixed a bug that caused undelimited
                                           dates to be handled incorrectly. They
                                           are now parsed against the full date
                                           output format then checked for validity.
                                           Thanks to Dan Wood for raising this bug.

                                          Fixed Standards-based (non IE)
                                           calendar dragging which wasn't releasing
                                           the calendar onmouseup.

                                          Fixed problem where selected weekdays
                                           carried over from one call to another
                                           on the same calendar object.

                                          Corrected the Month and Year select box
                                           displays in Opera. They were not changing
                                           when the month was shifted using the
                                           calendar's left and right arrows.

                                          Extended IFRAME backing to all calendar objects
                                           in order to improve calendar display over
                                           some embedded applets and objects.  Thanks to
                                           Stanko Kupcevic for his feedback on this.
                                           NOTE: It is not possible to protect any
                                           JavaScript object displayed over an
                                           embedded DYNAMIC (and, therefore refreshed)
                                           object because browsers usually do not
                                           directly control the screen handling within
                                           the object.  The best advice therefore remains
                                           to design pages in such a way that the calendar
                                           does not overlap embedded objects.

                                         Added curly braces and semi-colons
                                           for best practice and for robustness
                                           when code is compacted/obfuscated.

     0.90    2007-04-04  Anthony Garrett  Major re-write of the script to allow
                                           multiple calendar objects visible on
                                           on the page, and to allow static
                                           calendars. Dropped the legacy
                                           "showCal" entry-point function.

                                          Added ability to select calendar
                                           position relative to return value
                                           element.  Thanks to Justin Lawrence
                                           for that request.

*///*****************************************************************************

// ********************************************************
// Start of Javascript Advanced Calendar Script (JACS) Code
// ********************************************************

/* *****************************************************************************

    EXPOSED CALENDAR OBJECTS (FUNCTIONS):

        JACS.make   Creates calendar objects;
                        is called as part of JACS.show (if needed) but can also
                        be called to create a calendar instance at any time.

        JACS.show   Entry point for display of a calendar: Called in main page.

        JACS.next   Sets up a function that runs when a date is selected on a
                    static calendar or a dynamic calendar moves or closes.

        JACS.cals   returns an array of all the calendar IDs that have been
                    used on the page.

                    NOTES: 1 "used" here means: Invoked with JACS.make or JACS.show.
                             Calls without a defined calendar ID invoke the default
                             ID, 'jacs'.

                           2 Each calendar structure is added to the page when it
                             is first used. So this array may not hold all dynamic
                             calendar IDs that are defined on the page.  If you
                             want to be sure that the array does show all of them,
                             explicitly invoke  JACs.make(<<ID>>); for each ID on
                             page load.

*///*****************************************************************************

//  Namespace JACS
//  --------------
//  This namespace encapsulates all the calendar script code eliminating
//  naming conflicts between the JavaScript in this script and your calling
//  page(s) [as long as you don't use JACS as a variable of course].  It is
//  still possible for CSS inheritance to cause problems but that is unavoidable.

var JACS = new function()
    {// This date is used throughout to determine today's date.
     var dateNow = new Date(Date.parse(new Date().toDateString()));

     // This array keeps track of the defined calendars for the page.
     var cals = new Array();
     var _dList=new Array();
     var _bYear,_dYear;
     var _fDay, _bDay;
     var _xBase;

     // This function shortens the code replacing
     // document.getElementById('myID') with getEl('myId')
     // everywhere in the script. It also tries to handle a common
     // error when calling the script: when the developer has only
     // set a NAME attribute value, so no ID attribute is set.
     function getEl(id)
         {if (document.getElementById(id) || (!document.getElementById(id) && document.getElementsByName(id).length==0))
                                    // IF   An ID attribute is assigned
                                    // OR   No ID attribute is assigned but using IE and Opera
                                    //          (which will find the NAME attribute value using getElementById)
                                    // OR   No element has this ID or NAME attribute value
                                    //          (used internally by the script)
                                    // THEN Return the required element.
                {return document.getElementById(id);}
          else  {if (document.getElementsByName(id).length==1)
                                    // IF   No ID attribute is assigned
                                    // AND  Using a standards-based browser
                                    // AND  Only one element has the NAME attribute set to the value
                                    // THEN Return the required element (using the NAME attribute value).
                        {return document.getElementsByName(id)[0];}
                 else   {if (document.getElementsByName(id).length>1)
                                {   // IF   No ID attribute is assigned
                                    // AND  using a standards-based browser
                                    // AND  more than one element has the NAME attribute set to the value
                                    // THEN alert developer to fix the fault.
                                 alert( 'JACS' +
                                        ' \nCannot uniquely identify element named: ' + id +
                                        '.\nMore than one identical NAME attribute defined' +
                                        '.\nSolution: Assign the required element a unique ID attribute value.');
                                }
                        }
                }
         };


     function calAttributes(cal)
        {switch (cal.id)
            {case 'EnterYourIDHere':

                // If you want to vary the attributes for a specific instance
                // of the calendar, replace 'EnterYourIDHere' (above) with the
                // ID that you have defined for that calendar then amend and
                // uncomment the block-commented section below (which is just
                // a copy of the default section below with all the
                // documentation comments removed).

                /*

                cal.zIndex                   = 1;
                cal.baseYear                 = dateNow.getFullYear()-10;
                cal.dropDownYears            = 20;
                cal.weekStart                = 1;
                cal.weekNumberBaseDay        = 4;
                cal.weekNumberDisplay        = false;

                try   {jacsSetLanguage(cal);}
                catch (exception)
                    {cal.today               = 'Today:';
                     cal.clear               = 'Clear';
                     cal.drag                = 'click here to drag';
                     cal.monthNames          = ['Jan','Feb','Mar','Apr','May','Jun',
                                                'Jul','Aug','Sep','Oct','Nov','Dec'];
                     cal.weekInits           = ['S','M','T','W','T','F','S'];
                     cal.invalidDateMsg      = 'The entered date is invalid.\n';
                     cal.outOfRangeMsg       = 'The entered date is out of range.';
                     cal.doesNotExistMsg     = 'The entered date does not exist.';
                     cal.invalidAlert        = ['Invalid date (',') ignored.'];
                     cal.dateSettingError    = ['Error ',' is not a Date object.'];
                     cal.rangeSettingError   = ['Error ',' should consist of two elements.'];
                    }

                cal.showInvalidDateMsg       = true;
                cal.showOutOfRangeMsg        = true;
                cal.showDoesNotExistMsg      = true;
                cal.showInvalidAlert         = true;
                cal.showDateSettingError     = true;
                cal.showRangeSettingError    = true;
                cal.delimiters               = ['/','-','.',':',',',' '];
                cal.dateDisplayFormat        = 'dd-mm-yy';
                cal.dateFormat               = 'DD MMM, YYYY';
                cal.strict                   = false;
                cal.dates                    = new Array();
                cal.higlightDates            = new Array();
                cal.dayCells                 = [true, true, true, true, true, true, true,
                                                true, true, true, true, true, true, true,
                                                true, true, true, true, true, true, true,
                                                true, true, true, true, true, true, true,
                                                true, true, true, true, true, true, true,
                                                true, true, true, true, true, true, true];
                cal.outOfRangeDisable        = true;
                cal.outOfMonthDisable        = false;
                cal.outOfMonthHide           = false;
                cal.formatTodayCell          = true;
                cal.todayCellBorderColour    = 'red';
                cal.allowDrag                = false;
                cal.onBlurMoveNext           = false;
                cal.clickToHide              = false;
                cal.xBase                    = 'L';    // L Left, M Middle, R Right  or integer pixel offset from left
                cal.yBase                    = 'B';    // T Top,  M Middle, B Bottom or integer pixel offset from top
                cal.xPosition                = 'L';    // L Left, M Middle, R Right  or integer pixel offset from left
                cal.yPosition                = 'T';    // T Top,  M Middle, B Bottom or integer pixel offset from top
                cal.autoPosition             = true;
                */

                break;
             default:

                // cal.zIndex controls how the pop-up calendar interacts with
                // the rest of the page.  It is usually adequate to leave it
                // as 1 (One) but I have made it available here to help anyone
                // who needs to alter the level in order to ensure that the
                // calendar displays correctly in relation to all other elements
                // on the page.

                cal.zIndex = 1;

                // Set the bounds for the calendar here...
                // If you want the year to roll forward you can use something
                // like this...
                //      var baseYear = dateNow.getFullYear()-5;
                // alternatively, hard code a date like this...
                //      var baseYear = 1990;

                cal.baseYear = dateNow.getFullYear()+(_bYear!=undefined?_bYear:-10);

                // How many years do want to be valid and to show in the
                // drop-down list?

                cal.dropDownYears = _dYear?_dYear:20;

                // weekStart determines the start of the week in the display
                // Set it to: 0 (Zero) for Sunday, 1 (One) for Monday etc..

                // Note:  Always start the weekInits array with your
                //        string for Sunday whatever weekStart (below)
                //        is set to.

                cal.weekStart = 0;

                // Week numbering rules are generally based on a day in the week
                // that determines the first week of the year.  ISO 8601 uses
                // Thursday (day four when Sunday is day zero).  You can alter
                // the base day here.

                // See http://www.cl.cam.ac.uk/~mgk25/iso-time.html
                // for more information

                cal.weekNumberBaseDay = 4;

                // The week start day for the display is taken as the week start
                // for week numbering.  This ensures that only one week number
                // applies to one line of the calendar table.
                // [ISO 8601 begins the week with Day 1 = Monday.]

                // If you want to see week numbering on the calendar, set
                // this to true.  If not, false.

                cal.weekNumberDisplay = false;

                // If the calendar is given a date that it can't parse a month
                // from, it will use a default month.  If the following attribute
                // is FALSE then the default month is month 6 (June), if set to
                // TRUE then the default will be the current month.

                cal.defaultToCurrentMonth = false;

                // All language-dependent settings can be made here...

                // If you wish to work in a single language (other than English)
                // then just replace the English below with your own text.

                // Using multiple languages:
                // In order to keep this script to a resonable size I have not
                // included multiple languages here.  However, you can set the language
                // fields in a function that you should name  jacsSetLanguage.  The script
                // will then use your languages. I have included all the translations
                // that have been sent to me in such a function on my demonstration
                // site at http://www.tarrget.info/calendar/jacsLanguages.js.

                // gb
                cal.language            = 'gb';
                cal.today               = '今天:';
                cal.clear               = '清除';
                cal.drag                = 'click here to drag';
                cal.monthNames          = ['1月','2月','3月','4月','5月','6月',
                                           '7月','8月','9月','10月','11月','12月'];
                cal.weekInits           = ['日','一','二','三','四','五','六'];
                cal.invalidDateMsg      = 'The entered date is invalid.\n';
                cal.outOfRangeMsg       = 'The entered date is out of range.';
                cal.doesNotExistMsg     = 'The entered date does not exist.';
                cal.invalidAlert        = ['Invalid date (',') ignored.'];
                cal.dateSettingError    = ['Error ',' is not a Date object.'];
                cal.rangeSettingError   = ['Error ',' should consist of two elements.'];

                // Each of the calendar's alert message types can be disabled
                // independently here.

                cal.showInvalidDateMsg      = false;
                cal.showOutOfRangeMsg       = true;
                cal.showDoesNotExistMsg     = true;
                cal.showInvalidAlert        = true;
                cal.showDateSettingError    = true;
                cal.showRangeSettingError   = true;

                // Set the whole calendar as active (dates selectable)
                // or inactive (display only)

                cal.active = true;

                // Set the allowed input date delimiters here...
                // E.g. To set the rising slash, hyphen, full-stop (aka stop or
                //      point), colon, comma and space as delimiters use
                //              var cal.delimiters   = ['/','-','.',':',',',' '];

                cal.delimiters = ['/','-','.',':',',',' '];

                // Set the format for the displayed 'Today' date and for the
                // output date here.
                //
                // The format is described using delimiters of your choice (as
                // set in cal.delimiters above) and case insensitive letters
                // D, M and Y.
                //
                // NOTE: If no delimiters are input then the date output format is used
                //       to parse the value.  This allows less flexiblility in the input
                //       value than using delimiters but an accurately entered date
                //       remains parsable.

                // Displayed "Today" date format

                //cal.dateDisplayFormat = 'dd/mm/yyyy';     // e.g. 'MMM-DD-YYYY' for the US
                cal.dateDisplayFormat = 'yyyy/MM/dd';

                // Output date format

                //cal.dateFormat  = 'DD-MMM-YYYY'; // e.g. 'MMM-DD-YYYY' for the US
                cal.dateFormat  = 'yyyy-M-d';
                
                // Note: The delimiters used should be in cal.delimiters.

                // Personally I like the fact that entering 31-Sep-2005 (a date
                // that doesn't exist) displays 1-Oct-2005, however you may want
                // that to be an error.  If so, set cal.strict = true.  That
                // will cause an error message to display and the selected month
                // is displayed without a selected day. Thanks to Brad Allan for
                // his feedback prompting this feature.

                cal.strict = false;

                // If you are using ReadOnly or diaabled fields to return the date
                // value into, it can be useful to show a button on the calendar
                // that allows  the value to be cleared.  If you want to do that,
                // set cal.clearButton = true;

                cal.clearButton = true;

                // Choose whether the dates and days you specify in cal.dates
                // and as parameters to the JACS.show call are enabled (with all
                // other dates disabled) or disabled (with all other dates enabled).

                cal.valuesEnabled = false;

                // If you wish to set any displayed day, e.g. Every Monday,
                // you can do it using the following array.  The array elements
                // match the displayed cells.
                //
                // With the valuesEnabled attribute FALSE you could put something
                // like the following in your calling page to disable all weekend
                // days;
                //
                //  for (var i=0;i<<<calendar object>>.dayCells.length;i++)
                //      {if (i%7%6==0) <<calendar object>>.dayCells[i] = false;}
                //
                // The above approach will allow you to select days of the week
                // for the whole of your page easily.  If you need to set different
                // selected days for a number of date input fields on your page
                // there is an easier way: You can pass optional arguments to
                // JACS.show. The syntax is described at the top of this script in
                // the section:
                //    "How to use the Calendar once it is defined for your page:"
                //
                // It is possible to use these two approaches in combination.

                cal.dayCells = [true, true, true, true, true, true, true,
                                true, true, true, true, true, true, true,
                                true, true, true, true, true, true, true,
                                true, true, true, true, true, true, true,
                                true, true, true, true, true, true, true,
                                true, true, true, true, true, true, true];

                // You can specify any date (e.g. 24-Jan-2006 or Today) by creating
                // an element of the array cal.dates as a date object with the
                // value you want to handle.  Date ranges can be handled by placing
                // an array of two values (Start and End) into an element of this array.
                //
                // Use cal.valuesEnabled to determine whether any specified dates
                // are treated as the only enabled ones or the only disabled ones.

                cal.dates = new Array();
                
                // add by c
                if(_dList.length>0)
                {
                	for(var i=0;i<_dList.length;cal.dates.push(_dList[i++]));
                }
               	if (_fDay!=undefined && _bDay!=undefined) {
                	cal.dates.push(
                    	[new Date(cal.baseYear,0,0),
                         new Date(dateNow.getFullYear(),
                         dateNow.getMonth(),
                         dateNow.getDate()+_fDay)]);
                	cal.dates.push(
                    	[new Date(dateNow.getFullYear(),
                         dateNow.getMonth(),
                         dateNow.getDate()+_fDay+_bDay+1),
                         new Date(cal.dropDownYears+cal.baseYear,12,31)]);
                }
				else if (_fDay!=undefined)
					cal.dates.push(
						[new Date(cal.baseYear,0,1),
						new Date(dateNow.getFullYear(),
						dateNow.getMonth(),
						dateNow.getDate()+_fDay)]);

                // e.g. To specify 10-Dec-2005:
                //          cal.dates[0] = new Date(2005,11,10);
                //
                //      Or a range from 2004-Dec-25 to 2005-Jan-01:
                //
                //          cal.dates[1] =
                //              [new Date(2004,11,25),new Date(2005,0,1)];
                //
                //      The following will specify all calendar dates up to
                //      yesterday:
                //
                //          cal.dates[2] =
                //              [new Date(cal.baseYear,0,1),
                //               new Date(dateNow.getFullYear(),
                //                        dateNow.getMonth(),
                //                        dateNow.getDate()-1)];
                //
                // Remember that Javascript months are zero-based.

                // Allow specified dates to be highlighted when they are enabled.
                // You can set individual dates or date ranges in the same way as
                // above.

                cal.highlightDates = new Array();

                // Dates that are out of the specified range can be displayed at
                // the start of the very first month and end of the very last.
                // Set outOfRangeDisable = true to disable these dates
                // (or false to allow their selection).

                cal.outOfRangeDisable = true;

                // Dates that are out of the displayed month are shown at the start
                // (unless the month starts on the first day of the week) and end of
                // each month. Set outOfMonthDisable = true to disable these dates
                // (or false to allow their selection). Set outOfMonthHide = true
                // to hide these dates (or false to make them visible).

                cal.outOfMonthDisable = false;
                cal.outOfMonthHide    = false;

                // If you want a special format for the cell that contains the current day
                // set this to true.  This sets a thin border around the cell in the colour
                // set by cal.todayCellBorderColour.

                cal.formatTodayCell = true;
                cal.todayCellBorderColour = '#f00'; // red

                // You can allow the calendar to be dragged around the screen by
                // using the setting allowDrag = true.
                // I can't say I recommend it because of the danger of the user
                // forgetting which date field the calendar will update when
                // there are multiple date fields on a page.

                cal.allowDrag = false;

                // It is not easy to code HTML events to make the focus move
                // automatically on to the next element in the tab order so
                // here is a parameter you can set that will tell the script
                // to do it for you.  NOTE: The script may have to build a list
                // of all the page's elements in tabIndex order to achieve this
                // so there can be an overhead to using this feature.

                cal.onBlurMoveNext = false;

                // You can allow a click on the calendar to close dynamic
                // calendars by setting clickToHide = true.  If set to false
                // the script will hide a dynamic calendar when a date is
                // selected or the main page is clicked.

                cal.clickToHide = false;

                // Dynamic calendar positioning is relative to the return value
                // element. The script is supplied with the parameters below
                // setting the calendar's top left corner to appear at the
                // return element's bottom left corner.

                //cal.xBase     = 'L';
                cal.xBase     =  _xBase?_xBase:'L';
                cal.yBase     = 'B';
                cal.xPosition = 'L';
                cal.yPosition = 'T';

                // For the horizontal (X) parameters, xBase and xPosition,
                // the accepted values are;  L - Left
                //                           M - Middle
                //                           R - Right
                //                      or  nn - integer pixel offset from left +/-
                //
                // For the vertical (Y) parameters, yBase and yPosition,
                // the accepted values are;  T - Top
                //                           M - Middle
                //                           B - Bottom
                //                      or  nn - integer pixel offset from top +/-

                // The calendar will position itself aligned according to the
                // choices above.  If automatic positioning is turned
                // on  with  cal.autoPosition = true  then if the chosen position
                // would cause the calendar to display off the visible screen,
                // it is shifted to a position that is visible.

                cal.autoPosition = true;

            }

            // Do not set the value of this calendar attribute.  It is used
            // to tell you whether a date has been selected or not when
            // using the JACS.next feature to trigger a function after the
            // calendar is used.
            // dateReturned is False unless the user has clicked on an
            // active date cell or the value for "Today", in which case
            // it is True.

            cal.dateReturned  = false;

            // The most recent date output to the target element is stored
            // as an attribute of the calendar. Initialised to Midnight
            // on 1st January 1970 (UTC), a selected date can never
            // equal this because returned dates are always 12 Midday.

            cal.outputDate    = new Date(0);

            // Finally: The following attributes are used in calendar
            //          functions.  You need do nothing with them here.

            cal.seedDate      = new Date();
            cal.fullInputDate = false;
            cal.activeToday   = true;
            cal.monthSum      = 0;
            cal.days          = new Array();
            cal.arrOnNext     = new Array();
            cal.triggerEle;
            cal.targetEle;
        };

//******************************************************************************
//------------------------------------------------------------------------------
// End of customisation section
//------------------------------------------------------------------------------
//******************************************************************************

// *******************************************************
// Custom methods for Date, String and Function prototypes
// *******************************************************

     // Format a date into the required pattern

     Date.prototype.jacsFormat =
        function(format,monthNames)
            {var charCount = 0,
                 codeChar  = '',
                 result    = '';

             for (var i=0;i<=format.length;i++)
                {if (i<format.length && format.charAt(i)==codeChar)
                        {// If we haven't hit the end of the string and
                         // the format string character is the same as
                         // the previous one, just clock up one to the
                         // length of the current element definition
                         charCount++;
                        }
                 else   {switch (codeChar)
                            {case 'y': case 'Y':
                                result += (this.getFullYear()%Math.pow(10,charCount)).toString().jacsPadLeft(charCount);
                                break;
                             case 'm': case 'M':
                                // If we find an M, check the number of them to
                                // determine whether to get the month number or
                                // the month name.
                                result += (charCount<3)
                                            ?(this.getMonth()+1).toString().jacsPadLeft(charCount)
                                            :monthNames[this.getMonth()];
                                break;
                             case 'd': case 'D':
                                // If we find a D, get the date and format it
                                result += this.getDate().toString().jacsPadLeft(charCount);
                                break;
                             default:
                                // Copy any unrecognised characters across
                                while (charCount-->0) {result += codeChar;}
                            }

                         if (i<format.length)
                            {// Store the character we have just worked on
                             codeChar  = format.charAt(i);
                             charCount = 1;
                            }
                        }
                }
             return result;
            };

     // Left pad zeroes

     String.prototype.jacsPadLeft =
        function(padToLength)
            {var result = '';
             for (var i=0;i<(padToLength-this.length);i++) {result += '0'};
             return (result+this);
            };

     // Set up a closure so that any next function can be triggered after the calendar
     // has been closed AND that function can take arguments.

     Function.prototype.jacsRunNext =
        function()  {var func = this, args = arguments[0];
                     func.JACSid = arguments[1];
                     return function() {return func.apply(this, args);};
                    };

// **************************************
// Set up calendar events on calling page
// **************************************

     if (document.addEventListener)
          {window.addEventListener(  'load',jacsLoader,true);}
     else {window.attachEvent     ('onload',jacsLoader);}

     function jacsLoader()
        {// Define document level event to hide the calendar on click.

         if (document.addEventListener)
              {document.addEventListener('click',hide, false);}
         else {document.attachEvent('onclick',hide);}

         // Create an onBeforeUnload event to handle IE memory leaks.

         if (getEl('jacsIElt7')) {window.attachEvent('onbeforeunload',defeatLeaks);}

         function defeatLeaks()
            {for (var i=0;i<cals.length;i++)
                {// Display the week number column (header and row numbers).
                 getEl(cals[i]+'Week_').style.display='';

                 for (var j=0;j<6;j++) {getEl(cals[i]+'Week_'+j).style.display='';}

                 // Set events to null.

                 getEl(cals[i]+'Now').onclick         = null;
                 getEl(cals[i]+'Now').onmouseover     = null;
                 getEl(cals[i]+'Now').onmouseout      = null;
                 getEl(cals[i]+'ClearButton').onclick = null;

                 var cal    = getEl(cals[i]),
                     cells  = getEl(cals[i]+'Cells').childNodes;

                 for (var j=0;j<cells.length;j++)
                    {var rows = cells[j].childNodes;
                     for (var k=1;k<rows.length;k++)
                        {rows[k].onclick     = null;
                         rows[k].onmouseover = null;
                         rows[k].onmouseout  = null;
                        }
                    }

                 // Set calendar's leaky custom attributes to null.

                 cal.arrOnNext  = null;
                 cal.targetEle  = null;
                }
            };
        };

// ****************************************************************************
// Start of Main Private Function Library
// ****************************************************************************

     function showMonth(bias,calId)
        {// Set the selectable Month and Year
         // May be called: from the left and right arrows
         //                  (shift month -1 and +1 respectively)
         //                from the month selection list
         //                from the year selection list
         //                from the showCal routine
         //                  (which initiates the display).
         var cal       = getEl(calId),
             showDate  = new Date(Date.parse(new Date().toDateString())),
             startDate = new Date();

         // Set the time to the middle of the day so that the handful of
         // regions that have daylight saving shifts that change the day
         // of the month (i.e. turn the clock back at midnight or forward
         // at 23:00) do not mess up the date display in the calendar.

         showDate.setHours(12);

         selYears  = getEl(calId+'Years');
         selMonths = getEl(calId+'Months');

         if ( selYears.options.selectedIndex>-1) {cal.monthSum =12*(selYears.options.selectedIndex)+bias;}
         if (selMonths.options.selectedIndex>-1) {cal.monthSum+=selMonths.options.selectedIndex;}

         showDate.setFullYear(cal.baseYear+Math.floor(cal.monthSum/12),(cal.monthSum%12),1);

         // If the Week numbers are displayed, shift the week day names to the right.

         getEl(calId+'Week_').style.display = (cal.weekNumberDisplay)?'':'none';

         // Opera has a bug with setting the selected index.
         // It requires the following work-around to force SELECTs to display correctly.
         if (window.opera)
            {selMonths.style.display = 'inherit';
              selYears.style.display = 'inherit';
            }

         tmp = (12*parseInt((showDate.getFullYear()-cal.baseYear),10)) + parseInt(showDate.getMonth(),10);

         if (tmp > -1 && tmp < (12*cal.dropDownYears))
            {selYears.options.selectedIndex  = Math.floor(cal.monthSum/12);
             selMonths.options.selectedIndex = (cal.monthSum%12);

             curMonth = showDate.getMonth();

             showDate.setDate((((showDate.getDay()-cal.weekStart)<0)?-6:1)+cal.weekStart-showDate.getDay());

             var compareDateValue = new Date(showDate.getFullYear(),showDate.getMonth(),showDate.getDate()).valueOf();

             startDate = new Date(showDate);

             var now = getEl(calId+'Now');

             function nowOutput() {setOutput(dateNow,calId);};

             if (cal.dates.length==0)
                {if (cal.active && cal.activeToday)
                    {now.onclick   = nowOutput;
                     now.className = 'jacsNow';

                     if (getEl('jacsIE'))
                        {now.onmouseover = changeClass;
                         now.onmouseout  = changeClass;
                        }

                     if (document.removeEventListener)
                            {now.removeEventListener('click',stopPropagation,false);}
                     else   {now.detachEvent(      'onclick',stopPropagation);}
                    }
                 else
                    {now.onclick   = null;
                     now.className = 'jacsNowDisabled';

                     if (getEl('jacsIE'))
                        {now.onmouseover = null;
                         now.onmouseout  = null;
                        }

                     if (document.addEventListener)
                            {now.addEventListener('click',stopPropagation,false);}
                     else   {now.attachEvent(   'onclick',stopPropagation);}
                    }
                }
             else
                {for (var k=0;k<cal.dates.length;k++)
                    {if (!cal.activeToday ||
                         (typeof cal.dates[k]=='object' &&
                              ((cal.dates[k].constructor==Date  && dateNow.valueOf() == cal.dates[k].valueOf()) ||
                               (cal.dates[k].constructor==Array && dateNow.valueOf() >= cal.dates[k][0].valueOf() &&
                                                                   dateNow.valueOf() <= cal.dates[k][1].valueOf()
                               )
                              )
                         )
                        )
                        {now.onclick   = (cal.active && cal.valuesEnabled)?nowOutput:null;
                         now.className = (cal.active && cal.valuesEnabled)?'jacsNow':'jacsNowDisabled';

                         if (getEl('jacsIE'))
                            {now.onmouseover = (cal.active && cal.valuesEnabled)?changeClass:null;
                             now.onmouseout  = (cal.active && cal.valuesEnabled)?changeClass:null;
                            }

                         if (cal.active && cal.valuesEnabled)
                            {if (document.removeEventListener) {now.removeEventListener('click',stopPropagation,false);}
                             else                              {now.detachEvent(      'onclick',stopPropagation);}
                            }
                         else
                            {if (document.addEventListener) {now.addEventListener('click',stopPropagation,false);}
                             else                           {now.attachEvent(   'onclick',stopPropagation);}
                            }

                         break;
                        }
                     else
                        {now.onclick   = (cal.active && cal.valuesEnabled)?null:nowOutput;
                         now.className = (cal.active && cal.valuesEnabled)?'jacsNowDisabled':'jacsNow';

                         if (getEl('jacsIE'))
                            {now.onmouseover = (cal.active && cal.valuesEnabled)?null:changeClass;
                             now.onmouseout  = (cal.active && cal.valuesEnabled)?null:changeClass;
                            }

                         if (cal.active && cal.valuesEnabled)
                            {if (document.addEventListener) {now.addEventListener('click',stopPropagation,false);}
                             else                           {now.attachEvent(   'onclick',stopPropagation);}
                            }
                         else
                            {if (document.removeEventListener) {now.removeEventListener('click',stopPropagation,false);}
                             else                              {now.detachEvent(      'onclick',stopPropagation);}
                            }
                        }
                    }
                }

             function setOutput(outputDate,calId)
                {var cal = getEl(calId);

                 if (typeof cal.targetEle.value == 'undefined')
                        {cal.triggerEle.textNode.replaceData(0,cal.triggerEle.len,outputDate.jacsFormat(cal.dateFormat,cal.monthNames));}
                 else   {cal.ele.value = outputDate.jacsFormat(cal.dateFormat,cal.monthNames);}

                 cal.dateReturned = true;
                 cal.outputDate   = outputDate;

                 if (cal.dynamic) {hide(calId);}
                 else {if (typeof cal.onNext!='undefined' && cal.onNext!=null) {cal.onNext();}
                       JACS.show(cal.ele,cal.id,cal.days);
                      }

                 if (cal.onBlurMoveNext)
                    {// if the target element has a tabIndex look for tabIndex+1
                     // if that exists then set the focus to it

                     var tagsToFind = 'INPUT;A;SELECT;TEXTAREA;BUTTON;AREA;OBJECT',
                         found      = false;

                     if (cal.ele.tabIndex>0)
                        {var tags = tagsToFind.split(';');

                         tagsOuterLoop:
                         for (var i=0;tags.length;i++)
                            {elementsByTag = document.getElementsByTagName(tags[i]);

                             for (var j=0;j<elementsByTag.length;j++)
                                {if (elementsByTag[j].tabIndex==(cal.ele.tabIndex+1) && !elementsByTag[j].disabled &&
                                     elementsByTag[j].type!='hidden' && elementsByTag[j].style.display!='none' &&
                                     elementsByTag[j].style.visibility!='hidden')
                                    {elementsByTag[j].focus();
                                     found = true;
                                     break tagsOuterLoop;
                                    }
                                }
                            }
                        }

                     // else do the full search to find the next element

                     if (!found)
                        {// find element tabIndices
                         function orderElements()
                            {var tabOrder  = new Array,
                                 unordered = new Array;

                             function elementArrays(ele)
                                {for (var i=0;i<ele.childNodes.length;i++)
                                    {var tempEle = ele.childNodes[i];
                                     if (tempEle.nodeType==1 && tempEle.style.display!='none' &&
                                         !tempEle.disabled   && tempEle.type!='hidden' &&
                                         tempEle.style.visibility!='hidden')
                                        {if (tagsToFind.indexOf(tempEle.tagName)>-1)
                                            {if (tempEle.tabIndex>0) {tabOrder[tempEle.tabIndex]  = tempEle}
                                             else                    {unordered[unordered.length] = tempEle}
                                            }
                                         elementArrays(tempEle);
                                        }
                                    }
                                };

                             elementArrays(document.body);

                             while (tabOrder.length>0 && tabOrder[0]==null) {tabOrder.shift();}

                             return tabOrder.concat(unordered);
                            };

                         var tabSequenced = orderElements();

                         // find the current element in tabIndex ordered array
                         // and set focus to the next element (or the first if
                         // the current is the last)

                         for (var i=0;i<tabSequenced.length;i++)
                            {if (tabSequenced[i]==cal.targetEle)
                                {if (i<(tabSequenced.length-1)) {tabSequenced[i+1].focus()}
                                 else                           {tabSequenced[0].focus()}
                                 break;
                                }
                            }
                        }
                    }
                 else
                    {if (!cal.targetEle.disabled      && cal.targetEle.style.display!='none' &&
                         cal.targetEle.type!='hidden' && cal.targetEle.style.visibility!='hidden')
                        {cal.targetEle.focus();}
                    }
                };

             function changeClass(evt)
                {var ele = eventTrigger(evt);

                 if (ele.nodeType==3) {ele=ele.parentNode;}

                 if (((evt)?evt.type:event.type)=='mouseover')
                    {switch (ele.className)
                        {case 'jacsCells':
                            ele.className = 'jacsCellsHover';        break;
                         case 'jacsCellsHighlighted':
                            ele.className = 'jacsCellsHighlightedHover';        break;
                         case 'jacsCellsExMonth':
                            ele.className = 'jacsCellsExMonthHover'; break;
                         case 'jacsCellsWeekend':
                            ele.className = 'jacsCellsWeekendHover'; break;
                         case 'jacsCellsHighlightedWeekend':
                            ele.className = 'jacsCellsHighlightedWeekendHover'; break;
                         case 'jacsNow':
                            ele.className = 'jacsNowHover';         break;
                         case 'jacsInputDate':
                            ele.className = 'jacsInputDateHover';
                        }
                    }
                 else
                    {switch (ele.className)
                        {case 'jacsCellsHover':
                            ele.className = 'jacsCells';             break;
                         case 'jacsCellsHighlightedHover':
                            ele.className = 'jacsCellsHighlighted';  break;
                         case 'jacsCellsExMonthHover':
                            ele.className = 'jacsCellsExMonth';      break;
                         case 'jacsCellsWeekendHover':
                            ele.className = 'jacsCellsWeekend';      break;
                         case 'jacsCellsHighlightedWeekendHover':
                            ele.className = 'jacsCellsHighlightedWeekend';      break;
                         case 'jacsNowHover':
                            ele.className = 'jacsNow';              break;
                         case 'jacsInputDateHover':
                            ele.className = 'jacsInputDate';
                        }
                    }
                 return true;
                };

             function eventTrigger(evt)
                {if (!evt) {evt = event;}
                 return evt.target||evt.srcElement;
                };

             function weekNumber(inDate)
                {// The base day in the week of the input date
                 var inDateWeekBase = new Date(inDate);

                 inDateWeekBase.setDate(inDateWeekBase.getDate() - inDateWeekBase.getDay() + cal.weekNumberBaseDay +
                                            ((inDate.getDay() > cal.weekNumberBaseDay)?7:0));

                 // The first Base Day in the year
                 var firstBaseDay = new Date(inDateWeekBase.getFullYear(),0,1);

                 firstBaseDay.setDate(firstBaseDay.getDate() - firstBaseDay.getDay() + cal.weekNumberBaseDay);

                 if (firstBaseDay<new Date(inDateWeekBase.getFullYear(),0,1))
                    {firstBaseDay.setDate(firstBaseDay.getDate()+7);}

                 // Start of Week 01
                 var startWeekOne = new Date(firstBaseDay - cal.weekNumberBaseDay + inDate.getDay());

                 if (startWeekOne>firstBaseDay) {startWeekOne.setDate(startWeekOne.getDate()-7);}

                 // Subtract the date of the current week from the date of the first week of the year to
                 // get the number of weeks in milliseconds.  Divide by the number of milliseconds in a
                 // week then round to no decimals in order to remove the effect of daylight saving.  Add
                 // one to make the first week, week 1.  Place a string zero on the front so that week
                 // numbers are zero filled.

                 var weekNo = '0'+(Math.round((inDateWeekBase - firstBaseDay)/604800000,0)+1);

                 // Return the last two characters in the week number string

                 return weekNo.substring(weekNo.length-2,weekNo.length);
                };

             // walk the DOM to display the dates.

             var cells = getEl(calId+'Cells').childNodes;

             for (var i=0;i<cells.length;i++)
                {var rows = cells[i];
                 if (rows.nodeType==1 && rows.tagName=='TR')
                    {tmpEl = rows.childNodes[0];
                     if (cal.weekNumberDisplay)
                          {//Calculate the week number using showDate
                           tmpEl.innerHTML = weekNumber(showDate);
                           tmpEl.style.borderColor =
                               (tmpEl.currentStyle)
                                    ?tmpEl.currentStyle['backgroundColor']
                                    :(document.defaultView.getComputedStyle)
                                        ?document.defaultView.getComputedStyle(tmpEl,null).backgroundColor
                                        :'';
                           tmpEl.style.display = '';
                          }
                     else  {tmpEl.style.display='none';}

                     for (var j=1;j<rows.childNodes.length;j++)
                        {var cols = rows.childNodes[j];
                         if (cols.nodeType==1 && cols.tagName=='TD')
                            {rows.childNodes[j].innerHTML = showDate.getDate();

                             var cell = rows.childNodes[j];

                             cell.style.visibility = (cal.outOfMonthHide &&
                                                      (showDate < (new Date(showDate.getFullYear(),curMonth,1,showDate.getHours())) ||
                                                       showDate > (new Date(showDate.getFullYear(),curMonth+1,0,showDate.getHours()))
                                                      )
                                                     )?'hidden':'inherit';

                             // Disable if the outOfRangeDisable option has been set and the current date
                             // is out of range or the cal.valuesEnabled option is true.
                             var disabled = cal.valuesEnabled;

                             if ((cal.outOfRangeDisable && (showDate < (new Date(cal.baseYear,0,1,12)) ||
                                                            showDate > (new Date(cal.baseYear+cal.dropDownYears,0,0,12))
                                                           )
                                 ) ||
                                 (cal.outOfMonthDisable && (showDate < (new Date(showDate.getFullYear(),curMonth,1,showDate.getHours())) ||
                                                            showDate > (new Date(showDate.getFullYear(),curMonth+1,0,showDate.getHours()))
                                                           )
                                 )
                                ) {disabled = true;}
                             else
                                {if ((cal.days.join().search(((j-1+(7*(i*cells.length/6))+cal.weekStart)%7))>-1) ||
                                      !cal.dayCells[j-1+(7*((i*cells.length)/6))]
                                    )   {disabled = !cal.valuesEnabled;} // Set (Disable or Enable) if the day is passed as a parameter of JACS.show
                                 else   {for (var k=0;k<cal.dates.length;k++)
                                            {if (typeof cal.dates[k]=='object' &&
                                                 ((cal.dates[k].constructor==Date  && compareDateValue == cal.dates[k].valueOf()) ||
                                                  (cal.dates[k].constructor==Array && compareDateValue >= cal.dates[k][0].valueOf() &&
                                                                                      compareDateValue <= cal.dates[k][1].valueOf()
                                                  )
                                                 )
                                                )
                                                {disabled = !cal.valuesEnabled;
                                                 break;
                                                }
                                            }
                                        }
                                }

                             if (disabled)
                                {rows.childNodes[j].onclick = null;

                                 if (getEl('jacsIE'))
                                    {rows.childNodes[j].onmouseover = null;
                                     rows.childNodes[j].onmouseout  = null;
                                    }

                                 cell.className=
                                    (showDate.getMonth()!=curMonth)
                                        ?'jacsCellsExMonthDisabled'
                                        :(cal.fullInputDate &&
                                          compareDateValue==
                                          cal.seedDate.valueOf())
                                            ?'jacsInputDateDisabled'
                                            :(showDate.getDay()%6==0)
                                                ?'jacsCellsWeekendDisabled'
                                                :'jacsCellsDisabled';

                                 cell.style.borderColor =
                                     (cal.formatTodayCell && showDate.toDateString()==dateNow.toDateString())
                                        ?cal.todayCellBorderColour
                                        :(cell.currentStyle)
                                            ?cell.currentStyle['backgroundColor']
                                            :(document.defaultView.getComputedStyle)
                                                ?document.defaultView.getComputedStyle(cell,null).backgroundColor
                                                :'';
                                }
                             else
                                {function cellOutput(evt)
                                    {var ele = eventTrigger(evt),
                                         outputDate = new Date(startDate);

                                     if (ele.nodeType==3) ele=ele.parentNode;

                                     outputDate.setDate(startDate.getDate() +
                                        parseInt(ele.id.substr(calId.length+5),10));

                                     setOutput(outputDate,calId);
                                    };

                                 if (cal.active)
                                    {rows.childNodes[j].onclick=cellOutput;}

                                 if (getEl('jacsIE'))
                                    {rows.childNodes[j].onmouseover = changeClass;
                                     rows.childNodes[j].onmouseout  = changeClass;
                                    }

                                 var highlighted = false;

                                 for (var k=0;k<cal.highlightDates.length;k++)
                                    {if (typeof cal.highlightDates[k]=='object' &&
                                         ((cal.highlightDates[k].constructor==Date  &&
                                           compareDateValue == cal.highlightDates[k].valueOf()) ||
                                          (cal.highlightDates[k].constructor==Array &&
                                           compareDateValue >= cal.highlightDates[k][0].valueOf() &&
                                           compareDateValue <= cal.highlightDates[k][1].valueOf()
                                          )
                                         )
                                        )
                                        {highlighted = true;
                                         break;
                                        }
                                    }

                                 cell.className=
                                     (showDate.getMonth()!=curMonth)
                                        ?'jacsCellsExMonth'
                                        :(cal.fullInputDate &&
                                          compareDateValue==
                                          cal.seedDate.valueOf())
                                            ?'jacsInputDate'
                                            :(showDate.getDay()%6==0)
                                                ?(highlighted)?'jacsCellsHighlightedWeekend':'jacsCellsWeekend'
                                                :(highlighted)?'jacsCellsHighlighted':'jacsCells';

                                 cell.style.borderColor =
                                     (cal.formatTodayCell && showDate.toDateString()==dateNow.toDateString())
                                        ?cal.todayCellBorderColour
                                        :(cell.currentStyle)
                                            ?cell.currentStyle['backgroundColor']
                                            :(document.defaultView.getComputedStyle)
                                                ?document.defaultView.getComputedStyle(cell,null).backgroundColor
                                                :'';
                               }

                             showDate.setDate(showDate.getDate()+1);
                             compareDateValue = new Date(showDate.getFullYear(),
                                                         showDate.getMonth(),
                                                         showDate.getDate()).valueOf();
                            }
                        }
                    }
                }
            }

         // Opera has a bug with setting the selected index.
         // It requires the following work-around to force SELECTs to display correctly.
         // Also Opera's poor dynamic rendering prior to 9.5 requires
         // the visibility to be reset to prevent garbage in the calendar
         // when the displayed month is changed.
         if (window.opera)
            {selMonths.style.display = 'inline';
              selYears.style.display = 'inline';
             cal.style.visibility = 'hidden';
             cal.style.visibility = 'inherit';
            }
        };

     function hide(instanceID)
        {if (typeof instanceID=='object')
                {for (var i=0;i<cals.length;i++) {hideOne(cals[i]);}}
         else   {hideOne(instanceID);}

         function hideOne(id)
            {cal = getEl(id);

             if (cal.dynamic)
                {cal.style.visibility = 'hidden';
                 getEl(id+'Iframe').style.visibility='hidden';
                 doNext(cal);
                }
            };
        };

     function doNext(cal)
        {if (cal.arrOnNext)
            {if (cal.arrOnNext.length > 0)
                 {cal.onNext = cal.arrOnNext.shift();
                  cal.onNext();
                  // Explicit null set to prevent closure causing memory leak
                  cal.onNext = null;
                 }
            }
        };

     function stopPropagation(evt)
       {if (evt.stopPropagation)
             {if (evt.target!=evt.currentTarget) {evt.stopPropagation(); evt.preventDefault();}}
        else {evt.cancelBubble = true;}
       };

     function toDate(d)
     {
         if(typeof d=='object')
         {
             return d;
         }
         var l=/[\-\/]/,n=/(\d{4})(\d{2})(\d{2})/;
         var a=l.test(d)?d.split(l):d.match(n).slice(1);
         return new Date(a[0],Number(a[1])-1,a[2]);
     };

// *********************************
//   End of Private Function Library
// *********************************
// Start of Public  Function Library
// *********************************

     return {show: function(ele)
                {// Check the type of any additional parameters.
                 // The optional string parameter is a calendar ID,
                 // Take any remaining parameters as day numbers to be handled
                 // (enabled/disabled) according to the setting of the
                 // calendar's  valuesEnabled  attribute.
                 // 0 = Sunday through to 6 = Saturday.

                 if (typeof arguments[1]=='object')
                    {var dynamic = true;

                     if (typeof arguments[2]=='string')
                            {var calId = arguments[2], min = 3;}
                     else   {var calId = 'jacs',       min = 2;}

                     // Stop the click event that opens the calendar
                     // from bubbling up to the document-level event
                     // handler that hides it!

                     var source = arguments[1];
                     if (!source) {source = window.event;}

                     if (source.tagName)    // Second parameter isn't an event it's an element
                        {var sourceEle = source;
                         if (getEl('jacsIE'))  {window.event.cancelBubble = true;}
                         else {sourceEle.parentNode.addEventListener('click',stopPropagation,false);}
                        }
                     else   // Second parameter is an event
                        {var event = source;
                         // Stop the click event that opens the calendar from bubbling up to
                         // the document-level event handler that hides it!
                         var sourceEle = (event.target)?event.target:event.srcElement;
                         if (event.stopPropagation) {event.stopPropagation();}
                         else                       {event.cancelBubble = true;}
                        }
                    }
                 else
                    {var sourceEle = ele, dynamic = false;

                     if (typeof arguments[1]=='string')
                            {var calId = arguments[1], min = 2;}
                     else   {var calId = 'jacs',       min = 1;}
                    }

                 // Add event handlers to the return element and its parent.
                 // This helps the script to support tab sequences and focus events.

                 if (document.addEventListener)
                        {ele.addEventListener('keydown',hideOnTab,false);
                         ele.parentNode.addEventListener('click',stopPropagation,false);}
                 else   {ele.attachEvent('onkeydown',hideOnTab);
                         if (ele.parentNode!=document.body)
                            {ele.parentNode.attachEvent('onclick',stopPropagation);}
                        }

                 function hideOnTab(evt)
                    {if (!evt) {var evt = window.event;}
                     if ((evt.keyCode||evt.which)==9) {hide(calId);}
                    };

                 // Create the calendar structure. One is enough unless you want more
                 // than one calendar visible on the page at one time.  If you DO need
                 // more, you can create as many as you like but each must have a unique
                 // ID.

                 // The first parameter of JACS.make is the ID of the calendar. The
                 // second is a boolean that determines whether the calendar is to be
                 // static on the page (assigned to a single input field and always
                 // visible) or dynamic (shown and hidden on events and can be assigned
                 // to any number of input fields).

                 //if (!getEl(calId)) {JACS.make(calId,dynamic);}
                 var tmpCal = getEl(calId); // modify by c
                 var tmpIframe = getEl(calId+"Iframe");
                 if (tmpCal&&tmpIframe){tmpCal.parentNode.removeChild(tmpCal);tmpIframe.parentNode.removeChild(tmpIframe);}
                 JACS.make(calId,dynamic);

                 cal = getEl(calId);

                 // If the calendar has been triggered using an onfocus event,
                 // and the script actively returns the focus to the target
                 // element (i.e. when cal.onBlurMoveNext = false). We need
                 // to kill the event.

                 if (event)
                    {if (event.type == 'focus' && cal.dateReturned && !cal.onBlurMoveNext && cal.prevEventType == 'focus')
                        {stopPropagation(event); cal.prevEventType = ''; cal.dateReturned = false; return false;}
                     cal.prevEventType = event.type;
                    }

                 if (cal.style.visibility != 'hidden' &&
                     cal.style.visibility != 'inherit' &&
                     typeof doNext == 'function') {doNext(cal);}

                 cal.triggerEle = sourceEle;

                 cal.dateReturned = false;
                 cal.activeToday  = true;

                 // Set enabled/disabled days

                 if (arguments.length==min) {cal.days.length=0;}
                 else {selectedDays = (typeof arguments[min]=='object')?arguments[min]:arguments;
                       for (var i=(min|0);i<selectedDays.length;i++)
                         {if (cal.days.join().indexOf(selectedDays[i])==-1) {cal.days.push(selectedDays[i]);}}
                      }

                 for (var i=0;i<cal.days.length;i++)
                    {if (dateNow.getDay()==cal.days[i]%7) {cal.activeToday = false; break;}}

                 //   If no value is preset then the seed date is
                 //      Today (when today is in range) OR
                 //      The middle of the date range.

                 cal.seedDate = dateNow;

                 // Find the date and Strip space characters from start and
                 // end of date input.

                 var dateValue = '';

                 if (ele.value) {dateValue = ele.value.replace(/^\s+/,'').replace(/\s+$/,'');}
                 else   {if (typeof ele.value == 'undefined')
                            {var childNodes = ele.childNodes;
                             for (var i=0;i<childNodes.length;i++)
                                {if (childNodes[i].nodeType == 3)
                                    {dateValue = childNodes[i].nodeValue.replace(/^\s+/,'').replace(/\s+$/,'');
                                     if (dateValue.length > 0)
                                        {cal.triggerEle.textNode = childNodes[i];
                                         cal.triggerEle.len      = childNodes[i].nodeValue.length;
                                         break;
                                        }
                                    }
                                }
                            }
                        }

                 // Set the year range

                 var yearOptions = getEl(calId+'Years').options;

                 if (yearOptions.length==0 || yearOptions[0].value!=cal.baseYear)
                    {yearOptions.length = 0;
                     for (var i=0;i<cal.dropDownYears;i++) {yearOptions[i] = new Option((cal.baseYear+i),(cal.baseYear+i));}
                    }

                 if (dateValue.length==0)
                    {// If no value is entered and today is within the range,
                     // use today's date, otherwise use the middle of the valid range.

                     cal.fullInputDate=false;

                     if ((new Date(cal.baseYear+cal.dropDownYears,0,0))<cal.seedDate ||
                         (new Date(cal.baseYear,0,1))                  >cal.seedDate
                        )
                        {cal.seedDate = new Date(cal.baseYear+Math.floor(cal.dropDownYears / 2), 5, 1);}
                    }
                 else
                    {function inputFormat()
                        {var seed = new Array(),
                             input = dateValue.split(new RegExp('[\\'+cal.delimiters.join('\\')+']+','g'));

                         // "Escape" all the user defined date delimiters above -
                         // several delimiters will need it and it does no harm for
                         // the others.

                         // Strip any empty array elements (caused by delimiters)
                         // from the beginning or end of the array. They will
                         // still appear in the output string if in the output
                         // format.

                         if (input[0]!=null)
                            {if (input[0].length==0)              {input.splice(0,1);}
                             if (input[input.length-1].length==0) {input.splice(input.length-1,1);}
                            }

                         cal.fullInputDate = false;

                         cal.dateFormat = cal.dateFormat.toUpperCase();

                         // List all the allowed letters in the date format
                         var template = ['D','M','Y'];

                         // Prepare the sequence of date input elements
                         var result = new Array();

                         for (var i=0;i<template.length;i++)
                            {if (cal.dateFormat.search(template[i])>-1)
                                {result[cal.dateFormat.search(template[i])] = template[i];}
                            }

                         cal.dateSequence = result.join('');

                         // Separate the elements of the date input
                         switch (input.length)
                            {case 1:
                                {// Year only entry or undelimited date format

                                 if (cal.dateFormat.indexOf('Y')>-1 &&
                                     input[0].length>cal.dateFormat.lastIndexOf('Y'))
                                    {seed[0] = parseInt(input[0].substring(cal.dateFormat.indexOf('Y'),
                                                                           cal.dateFormat.lastIndexOf('Y')+1),10);
                                    }
                                 else   {seed[0] = parseInt(input[0],10);}

                                 if (cal.dateFormat.indexOf('M')>-1 &&
                                     input[0].length>cal.dateFormat.lastIndexOf('M'))
                                    {seed[1] = input[0].substring(cal.dateFormat.indexOf('M'),
                                                                  cal.dateFormat.lastIndexOf('M')+1);
                                    }
                                 else   {seed[1] = cal.defaultToCurrentMonth?(dateNow.getMonth()+1).toString():'6';}

                                 if (cal.dateFormat.indexOf('D')>-1 &&
                                     input[0].length>cal.dateFormat.lastIndexOf('D'))
                                    {seed[2] = parseInt(input[0].substring(cal.dateFormat.indexOf('D'),
                                                                           cal.dateFormat.lastIndexOf('D')+1),10);
                                    }
                                 else   {seed[2] = 1;}

                                 if (input[0].length==cal.dateFormat.length)    {cal.fullInputDate = true;}
                                 break;
                                }
                             case 2:
                                {// Year and Month entry
                                 seed[0] = parseInt(input[cal.dateSequence.replace(/D/i,'').search(/Y/i)],10);  // Year
                                 seed[1] = input[cal.dateSequence.replace(/D/i,'').search(/M/i)];               // Month
                                 seed[2] = 1;                                                                        // Day
                                 break;
                                }
                             case 3:
                                {// Day Month and Year entry
                                 seed[0] = parseInt(input[cal.dateSequence.search(/Y/i)],10);  // Year
                                 seed[1] = input[cal.dateSequence.search(/M/i)];               // Month
                                 seed[2] = parseInt(input[cal.dateSequence.search(/D/i)],10);  // Day
                                 cal.fullInputDate = true;
                                 break;
                                }
                             default:
                                {// A stuff-up has led to more than three elements in the date.
                                 seed[0] = 0;     // Year
                                 seed[1] = 0;     // Month
                                 seed[2] = 0;     // Day
                                }
                            }

                         // These regular expressions validate the input date format
                         // to the following rules;
                         //         Day   1-31 (optional zero on single digits)
                         //         Month 1-12 (optional zero on single digits)
                         //                     or case insensitive name
                         //         Year  One, Two or four digits

                         // Months names are as set in the language-dependent
                         // definitions and delimiters are set just below there

                         var expValDay    = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])$'),
                             expValMonth  = new RegExp('^(0?[1-9]|1[0-2]|'+cal.monthNames.join('|')+')$','i'),
                             expValYear   = new RegExp('^([0-9]{1,2}|[0-9]{4})$');

                         // Apply validation and report failures

                         if (expValYear.exec(seed[0]) ==null ||
                             expValMonth.exec(seed[1])==null ||
                             expValDay.exec(seed[2])  ==null
                            )
                            {if (cal.showInvalidDateMsg)
                                {alert(cal.invalidDateMsg + cal.invalidAlert[0] + dateValue + cal.invalidAlert[1]);}
                             seed[0] = cal.baseYear + Math.floor(cal.dropDownYears/2);                   // Year
                             seed[1] = cal.defaultToCurrentMonth?(dateNow.getMonth()+1).toString():'6';  // Month
                             seed[2] = 1;                                                                // Day
                             cal.fullInputDate = false;
                            }

                         // Return the Year  in seed[0]
                         //            Month in seed[1]
                         //            Day   in seed[2]

                         return seed;
                        };

                     // Parse the string into an array using the allowed delimiters

                     seedDate = inputFormat();

                     // So now we have the Year, Month and Day in an array.

                     //   If the year is one or two digits then the routine assumes a
                     //   year belongs in the 21st Century unless it is less than 50
                     //   in which case it assumes the 20th Century is intended.

                     if (seedDate[0]<100) {seedDate[0] += (seedDate[0]>50)?1900:2000;}

                     // Check whether the month is in digits or an abbreviation

                     if (seedDate[1].search(/\d+/)<0)
                        {for (i=0;i<cal.monthNames.length;i++)
                            {if (seedDate[1].toUpperCase()==cal.monthNames[i].toUpperCase())
                                {seedDate[1]=i+1;
                                 break;
                                }
                            }
                        }

                     cal.seedDate = new Date(seedDate[0],seedDate[1]-1,seedDate[2]);
                    }

                 // Test that we have arrived at a valid date

                 if (isNaN(cal.seedDate))
                    {if (cal.showInvalidDateMsg)
                        {alert(cal.invalidDateMsg + cal.invalidAlert[0] + dateValue + cal.invalidAlert[1]);}
                     cal.seedDate = new Date(cal.baseYear + Math.floor(cal.dropDownYears/2),5,1);
                     cal.fullInputDate = false;
                    }
                 else
                    {// Test that the date is within range,
                     // if not then set date to a sensible date in range.

                     if ((new Date(cal.baseYear,0,1))>cal.seedDate)
                        {if (cal.strict && cal.showOutOfRangeMsg) {alert(cal.outOfRangeMsg);}
                         cal.seedDate = new Date(cal.baseYear,0,1);
                         cal.fullInputDate=false;
                        }
                     else
                        {if ((new Date(cal.baseYear+cal.dropDownYears,0,0))<cal.seedDate)
                            {if (cal.strict && cal.showOutOfRangeMsg) {alert(cal.outOfRangeMsg);}
                             cal.seedDate = new Date(cal.baseYear + Math.floor(cal.dropDownYears),-1,1);
                             cal.fullInputDate=false;
                            }
                         else
                            {if (cal.strict && cal.fullInputDate &&
                                  (cal.seedDate.getDate()     !=seedDate[2] ||
                                   (cal.seedDate.getMonth()+1)!=seedDate[1] ||
                                   cal.seedDate.getFullYear() !=seedDate[0]
                                  )
                                )
                                {if (cal.showDoesNotExistMsg) {alert(cal.doesNotExistMsg);}
                                 cal.seedDate = new Date(cal.seedDate.getFullYear(),cal.seedDate.getMonth()-1,1);
                                 cal.fullInputDate=false;
                                }
                            }
                        }
                    }

                 // Test the chosen dates for validity
                 // Give error message if not valid

                 for (var i=0;i<cal.dates.length;i++)
                    {if (!((typeof cal.dates[i]=='object') && (cal.dates[i].constructor==Date)))
                        {if ((typeof cal.dates[i]=='object') && (cal.dates[i].constructor==Array))
                            {var pass = true;

                             if (cal.dates[i].length!=2)
                                {if (cal.showRangeSettingError)
                                    {alert(cal.rangeSettingError[0] + cal.dates[i] + cal.rangeSettingError[1]);}
                                 pass = false;
                                }
                             else
                                {for (var j=0;j<cal.dates[i].length;j++)
                                    if (!((typeof cal.dates[i][j]=='object') && (cal.dates[i][j].constructor==Date)))
                                        {if (cal.showRangeSettingError)
                                            {alert(cal.dateSettingError[0] + cal.dates[i][j] + cal.dateSettingError[1]);}
                                         pass = false;
                                        }
                                }

                             if (pass && (cal.dates[i][0]>cal.dates[i][1])) {cal.dates[i].reverse();}
                            }
                         else
                            {if (cal.showRangeSettingError)
                                {alert(cal.dateSettingError[0] + cal.dates[i] + cal.dateSettingError[1]);}
                            }
                        }
                    }

                 // Set language-dependent values

                 getEl(calId+'DragText').innerHTML = cal.drag;

                 var monthOptions = getEl(calId+'Months').options,  months = '';

                 if (monthOptions.length>0) {for (var i=0;i<monthOptions.length;i++) {months += monthOptions[i].value+',';}}

                 if (monthOptions.length==0 || (cal.monthNames.join()+',')!=months)
                    {monthOptions.length = 0;

                     if (cal.monthNames.length<monthOptions.length) {monthOptions.length = cal.monthNames.length;}

                     for (var i=0;i<cal.monthNames.length;i++)
                        {if (i>monthOptions.length-1)
                              {monthOptions[i] = new Option(cal.monthNames[i],cal.monthNames[i]);}
                         else {monthOptions[i].innerHTML = cal.monthNames[i];}
                        }
                    }

                 for (var i=0;i<cal.weekInits.length;i++)
                    {getEl(calId+'WeekInit'+i).innerHTML = cal.weekInits[(i+cal.weekStart)%cal.weekInits.length];}

                 if (((new Date(cal.baseYear + cal.dropDownYears, 0, 0)) > dateNow &&
                      (new Date(cal.baseYear, 0, 0))                     < dateNow) ||
                     (cal.clearButton && (ele.readOnly || ele.disabled))
                    )   {getEl(calId+'Now').innerHTML = cal.today+' '+dateNow.jacsFormat(cal.dateDisplayFormat,cal.monthNames);
                         getEl(calId+'ClearButton').value   = cal.clear;
                         getEl(calId+'Foot').style.display = '';

                         if ((new Date(cal.baseYear + cal.dropDownYears, 0, 0)) > dateNow &&
                             (new Date(cal.baseYear, 0, 0))                     < dateNow)
                                {getEl(calId+'Now').style.display = '';
                                 if (cal.clearButton && (ele.readOnly || ele.disabled))
                                        {getEl(calId+'Clear').style.display   = '';
                                         getEl(calId+'Clear').style.textAlign = 'left';
                                         getEl(calId+'Now'  ).style.textAlign = 'right';
                                        }
                                 else   {getEl(calId+'Clear').style.display   = 'none';
                                         getEl(calId+'Now'  ).style.textAlign = 'center';
                                        }
                                }
                         else   {getEl(calId+'Clear').style.textAlign = 'center';
                                 getEl(calId+'Clear').style.display   = '';
                                 getEl(calId+'Now'  ).style.display   = 'none';
                                }
                        }
                 else   {getEl(calId+'Foot').style.display = 'none';}

                 // Calculate the number of months that the entered (or
                 // defaulted) month is after the start of the allowed
                 // date range.
                 cal.monthSum =  12*(cal.seedDate.getFullYear() - cal.baseYear) + cal.seedDate.getMonth();

                 // Set the drop down boxes.
                 getEl(calId+'Years').options.selectedIndex  = Math.floor(cal.monthSum/12);
                 getEl(calId+'Months').options.selectedIndex = (cal.monthSum%12);

                 getEl(calId).ele = ele;

                 // Display the month
                 showMonth(0,calId);

                 // Remember the Element
                 cal.targetEle = ele;

                 // Position the calendar box.
                 if (dynamic)
                    {// Check whether or not dragging is allowed and display drag handle if necessary
                     getEl(calId+'Drag').style.display = (cal.allowDrag)?'':'none';

                     var offsetTop  = parseInt(ele.offsetTop ,10),
                         offsetLeft = parseInt(ele.offsetLeft,10);

                     // The object sniffing for Opera allows for the fact that Opera
                     // is the only major browser that correctly reports the position
                     // of an element in a scrollable DIV.  This is because IE and
                     // Firefox omit the DIV from the offsetParent tree.
                     if (!window.opera)
                         {while (ele.tagName!='BODY' && ele.tagName!='HTML')
                             {offsetTop  -= parseInt(ele.scrollTop, 10);
                              offsetLeft -= parseInt(ele.scrollLeft,10);
                              ele = ele.parentNode;
                             }
                          ele = cal.targetEle;
                         }

                     while (ele.tagName!='BODY' && ele.tagName!='HTML')
                        {ele = ele.offsetParent;
                         offsetTop  += parseInt(ele.offsetTop, 10);
                         offsetLeft += parseInt(ele.offsetLeft,10);
                        }

                     ele = cal.targetEle;

                     var eleOffsetTop  = offsetTop,
                         eleOffsetLeft = offsetLeft;

                     if (cal.xBase.length>0)
                            {if (isNaN(cal.xBase))
                                    {cal.xBase = cal.xBase.toUpperCase();
                                     offsetLeft += (cal.xBase=='R')
                                                        ?parseInt(ele.offsetWidth,10)
                                                        :(cal.xBase=='M')?Math.round(parseInt(ele.offsetWidth,10)/2):0;
                                    }
                             else   {offsetLeft += parseInt(cal.xBase,10);}
                            }

                     if (cal.yBase.length>0)
                            {if (isNaN(cal.yBase))
                                    {cal.yBase  = cal.yBase.toUpperCase();
                                     offsetTop += (cal.yBase=='B')
                                                    ?parseInt(ele.offsetHeight,10)
                                                    :(cal.yBase=='M')?Math.round(parseInt(ele.offsetHeight,10)/2):0;
                                    }
                             else   {offsetTop += parseInt(cal.yBase,10);}
                            }
                     else   {offsetTop += parseInt(ele.offsetHeight,10);}

                     if (cal.xPosition.length>0)
                            {if (isNaN(cal.xPosition))
                                    {cal.xPosition = cal.xPosition.toUpperCase();
                                     offsetLeft -= (cal.xPosition=='R')
                                                        ?parseInt(cal.offsetWidth,10)
                                                        :(cal.xPosition=='M')?Math.round(parseInt(cal.offsetWidth,10)/2):0;
                                    }
                             else   {offsetLeft += parseInt(cal.xPosition,10);}
                            }

                     if (cal.yPosition.length>0)
                            {if (isNaN(cal.yPosition))
                                    {cal.yPosition = cal.yPosition.toUpperCase();

                                     offsetTop -= (cal.yPosition=='B')
                                                        ?parseInt(cal.offsetHeight,10)
                                                        :(cal.yPosition=='M')?Math.round((parseInt(cal.offsetHeight,10))/2):0;
                                    }
                             else   {offsetTop += parseInt(cal.yPosition,10);}
                            }

                     if (cal.autoPosition)
                        {var width      = parseInt(cal.offsetWidth, 10),
                             height     = parseInt(cal.offsetHeight,10),
                             windowLeft =
                                 (document.body && document.body.scrollLeft)
                                      ?document.body.scrollLeft                  //DOM compliant
                                      :(document.documentElement && document.documentElement.scrollLeft)
                                          ?document.documentElement.scrollLeft   //IE6+ standards compliant
                                          :0,                                    //Failed
                             windowWidth =
                                  (typeof(innerWidth) == 'number')
                                      ?innerWidth                                //DOM compliant
                                      :(document.documentElement && document.documentElement.clientWidth)
                                          ?document.documentElement.clientWidth  //IE6+ standards compliant
                                          :(document.body && document.body.clientWidth)
                                              ?document.body.clientWidth         //IE non-compliant
                                              :0,                                //Failed
                             windowTop =
                                  (document.body && document.body.scrollTop)
                                      ?document.body.scrollTop                   //DOM compliant
                                      :(document.documentElement && document.documentElement.scrollTop)
                                          ?document.documentElement.scrollTop    //IE6+ standards compliant
                                          :0,                                    //Failed
                             windowHeight =
                                  (typeof(innerHeight) == 'number')
                                      ?innerHeight                               //DOM compliant
                                      :(document.documentElement && document.documentElement.clientHeight)
                                          ?document.documentElement.clientHeight //IE6+ standards compliant
                                          :(document.body && document.body.clientHeight)
                                              ?document.body.clientHeight        //IE non-compliant
                                              :0;                                //Failed

                         if (eleOffsetLeft + parseInt(ele.offsetWidth,10) - width >= windowLeft &&
                             offsetLeft + width > windowLeft + windowWidth
                            )       {offsetLeft = eleOffsetLeft + parseInt(ele.offsetWidth,10) - width;}
                         else if (eleOffsetLeft >= windowLeft && offsetLeft < windowLeft
                                 )  {offsetLeft = eleOffsetLeft;}

                         if (eleOffsetTop - height >= windowTop &&
                             offsetTop + height > windowTop + windowHeight
                            )       {offsetTop = eleOffsetTop - height;}
                         else if (offsetTop + height <= windowTop + windowHeight && offsetTop < windowTop)
                                    {offsetTop = eleOffsetTop + parseInt(ele.offsetHeight,10);}
                        }

                     cal.style.top  = offsetTop+'px';
                     cal.style.left = offsetLeft+'px';

                     getEl(calId+'Iframe').style.top    = offsetTop +'px';
                     getEl(calId+'Iframe').style.left   = offsetLeft+'px';

                     getEl(calId+'Iframe').style.width  = (cal.offsetWidth -(getEl('jacsIE')?2:4))+'px';
                     getEl(calId+'Iframe').style.height = (cal.offsetHeight-(getEl('jacsIE')?2:4))+'px';
                     getEl(calId+'Iframe').style.visibility = 'inherit';
                    }

                 // Show it on the page
                 cal.style.visibility = 'inherit';
                },

             make: function (calId)
                {cals.push(calId);

                 var dynamic = (typeof arguments[1]=='boolean')?arguments[1]:true;

                 TABLEjacs           = document.createElement('table');
                 TABLEjacs.id        = calId;
                 TABLEjacs.dynamic   = dynamic;
                 TABLEjacs.className = (dynamic)?'jacs':'jacsStatic';

                 calAttributes(TABLEjacs);

                 if (dynamic) {TABLEjacs.style.zIndex = TABLEjacs.zIndex+1;}

                 function cancel(evt)
                    {if (TABLEjacs.clickToHide) {hide(calId);}
                     stopPropagation(evt);
                    };

                 TBODYjacs                 = document.createElement('tbody');
                 TRjacs1                   = document.createElement('tr');
                 TRjacs1.className         = 'jacs';
                 TDjacs1                   = document.createElement('td');
                 TDjacs1.className         = 'jacs';
                 TABLEjacsHead             = document.createElement('table');
                 TABLEjacsHead.id          = calId+'Head';
                 TABLEjacsHead.cellSpacing = '0';
                 TABLEjacsHead.cellPadding = '0';
                 TABLEjacsHead.className   = 'jacsHead';
                 TABLEjacsHead.width       = '100%';

                 TBODYjacsHead             = document.createElement('tbody');

                 TRjacsDrag                = document.createElement('tr');
                 TRjacsDrag.id             = calId+'Drag';
                 TRjacsDrag.style.display  = 'none';

                 TDjacsDrag                = document.createElement('td');
                 TDjacsDrag.className      = 'jacsDrag';
                 TDjacsDrag.colSpan        = '4';

                 function beginDrag(evt)
                    {var elToDrag = getEl(calId);

                     var deltaX    = evt.clientX,
                         deltaY    = evt.clientY,
                         offsetEle = elToDrag;

                     while (offsetEle.tagName!='BODY' && offsetEle.tagName!='HTML')
                        {deltaX   -= parseInt(offsetEle.offsetLeft,10);
                         deltaY   -= parseInt(offsetEle.offsetTop ,10);
                         offsetEle = offsetEle.offsetParent;
                        }

                     if (document.addEventListener)
                            {elToDrag.addEventListener('mousemove',moveHandler,true);
                             elToDrag.addEventListener('mouseup',    upHandler,true);
                            }
                     else   {elToDrag.attachEvent('onmousemove', moveHandler);
                             elToDrag.attachEvent('onmouseup',     upHandler);
                             elToDrag.setCapture();
                            }

                     stopPropagation(evt);

                     function moveHandler(evt)
                        {if (!evt) {evt = window.event;}

                         elToDrag.style.left = (evt.clientX-deltaX)+'px';
                         elToDrag.style.top  = (evt.clientY-deltaY)+'px';

                         getEl(calId+'Iframe').style.left = (evt.clientX-deltaX)+'px';
                         getEl(calId+'Iframe').style.top  = (evt.clientY-deltaY)+'px';

                         stopPropagation(evt);
                        };

                     function upHandler(evt)
                        {if (!evt) {evt = window.event;}

                         if (document.removeEventListener)
                                {elToDrag.removeEventListener('mousemove',moveHandler,true);
                                 elToDrag.removeEventListener(  'mouseup',  upHandler,true);
                                }
                         else   {elToDrag.detachEvent('onmouseup',    upHandler);
                                 elToDrag.detachEvent('onmousemove',moveHandler);
                                 elToDrag.releaseCapture();
                                }

                         stopPropagation(evt);
                        };
                    };

                 DIVjacsDragText           = document.createElement('span');
                 DIVjacsDragText.id        = calId+'DragText';

                 TRjacsHead                = document.createElement('tr');
                 TRjacsHead.className      = 'jacsHead';

                 TDjacsHead1               = document.createElement('td');
                 TDjacsHead1.className     = 'jacsHead';

                 INPUTjacsHead1            = document.createElement('input');
                 INPUTjacsHead1.className  = 'jacsHead';
                 INPUTjacsHead1.id         = calId+'HeadLeft';
                 INPUTjacsHead1.type       = 'button';
                 INPUTjacsHead1.tabIndex   = '-1';
                 INPUTjacsHead1.value      = '<';
                 INPUTjacsHead1.onclick    = function() {showMonth(-1,calId);}

                 TDjacsHead2               = document.createElement('td');
                 TDjacsHead2.className     = 'jacsHead';

                 SELECTjacsHead2           = document.createElement('select');
                 SELECTjacsHead2.className = 'jacsHead';
                 SELECTjacsHead2.id        = calId+'Months';
                 SELECTjacsHead2.tabIndex  = '-1';
                 SELECTjacsHead2.onchange  = function() {showMonth(0,calId);}

                 TDjacsHead3               = document.createElement('td');
                 TDjacsHead3.className     = 'jacsHead';

                 SELECTjacsHead3           = document.createElement('select');
                 SELECTjacsHead3.className = 'jacsHead';
                 SELECTjacsHead3.id        = calId+'Years';
                 SELECTjacsHead3.tabIndex  = '-1';
                 SELECTjacsHead3.onchange  = function() {showMonth(0,calId);}

                 TDjacsHead4               = document.createElement('td');
                 TDjacsHead4.className     = 'jacsHead';

                 INPUTjacsHead4            = document.createElement('input');
                 INPUTjacsHead4.className  = 'jacsHead';
                 INPUTjacsHead4.id         = calId+'HeadRight';
                 INPUTjacsHead4.type       = 'button';
                 INPUTjacsHead4.tabIndex   = '-1';
                 INPUTjacsHead4.value      = '>';
                 INPUTjacsHead4.onclick    = function() {showMonth(1,calId);}

                 TRjacs2                   = document.createElement('tr');
                 TRjacs2.className         = 'jacs';

                 TDjacs2                   = document.createElement('td');
                 TDjacs2.className         = 'jacs';

                 TABLEjacsCells            = document.createElement('table');
                 TABLEjacsCells.className  = 'jacsCells';
                 TABLEjacsCells.align      = 'center';
                 TABLEjacsCells.width      = '100%';

                 THEADjacsCells            = document.createElement('thead');
                 TRjacsCells               = document.createElement('tr');
                 TDjacsCells               = document.createElement('td');
                 TDjacsCells.className     = 'jacsWeekNumberHead';
                 TDjacsCells.id            = calId+'Week_';

                 TABLEjacs.appendChild(TBODYjacs);
                 TBODYjacs.appendChild(TRjacs1);
                    TRjacs1.appendChild(TDjacs1);
                        TDjacs1.appendChild(TABLEjacsHead);
                            TABLEjacsHead.appendChild(TBODYjacsHead);
                                 TBODYjacsHead.appendChild(TRjacsDrag);
                                    TRjacsDrag.appendChild(TDjacsDrag);
                                        TDjacsDrag.appendChild(DIVjacsDragText);
                                 TBODYjacsHead.appendChild(TRjacsHead);
                                    TRjacsHead.appendChild(TDjacsHead3);
                                        TDjacsHead3.appendChild(SELECTjacsHead3);
                                    TRjacsHead.appendChild(TDjacsHead1);
                                        TDjacsHead1.appendChild(INPUTjacsHead1);
                                    TRjacsHead.appendChild(TDjacsHead2);
                                        TDjacsHead2.appendChild(SELECTjacsHead2);
                                    TRjacsHead.appendChild(TDjacsHead4);
                                        TDjacsHead4.appendChild(INPUTjacsHead4);
                 TBODYjacs.appendChild(TRjacs2);
                    TRjacs2.appendChild(TDjacs2);
                        TDjacs2.appendChild(TABLEjacsCells);
                            TABLEjacsCells.appendChild(THEADjacsCells);
                                THEADjacsCells.appendChild(TRjacsCells);
                                    TRjacsCells.appendChild(TDjacsCells);

                                    for (var i=0;i<7;i++)
                                        {TDjacsCells           = document.createElement('td');
                                         TDjacsCells.className = 'jacsWeek';
                                         TDjacsCells.id        = calId+'WeekInit'+i;
                                         TRjacsCells.appendChild(TDjacsCells);
                                        }

                            TBODYjacsCells    = document.createElement('tbody');
                            TBODYjacsCells.id = calId+'Cells';

                            TABLEjacsCells.appendChild(TBODYjacsCells);

                            for (var i=0;i<6;i++)
                                {TRjacsCells              = document.createElement('tr');
                                 TBODYjacsCells.appendChild(TRjacsCells);

                                    TDjacsCells           = document.createElement('td');
                                    TDjacsCells.className = 'jacsWeekNo';
                                    TDjacsCells.id        = calId+'Week_'+i;
                                    TRjacsCells.appendChild(TDjacsCells);

                                    for (var j=0;j<7;j++)
                                        {TDjacsCells           = document.createElement('td');
                                         TDjacsCells.className = 'jacsCells';
                                         TDjacsCells.id        = calId+'Cell_'+(j+(i*7));
                                         TRjacsCells.appendChild(TDjacsCells);
                                        }
                                }

                 TFOOTjacsFoot           = document.createElement('tfoot');
                 TABLEjacsCells.appendChild(TFOOTjacsFoot);

                    TRjacsFoot              = document.createElement('tr');
                    TRjacsFoot.id           = calId+'Foot';
                    TFOOTjacsFoot.appendChild(TRjacsFoot);

                    TDjacsFoot               = document.createElement('td');
                    TDjacsFoot.colSpan       = '8';
                    TDjacsFoot.style.padding = '0px';
                    TRjacsFoot.appendChild(TDjacsFoot);

                        TABLEjacsFootDetail = document.createElement('table');
                        TABLEjacsFootDetail.style.width = '100%';
                        TABLEjacsFootDetail.cellSpacing = '0';
                        TABLEjacsFootDetail.cellPadding = '0';
                        TDjacsFoot.appendChild(TABLEjacsFootDetail);

                            TBODYjacsFootDetail = document.createElement('tbody');
                            TABLEjacsFootDetail.appendChild(TBODYjacsFootDetail);

                                TRjacsFootDetail = document.createElement('tr');
                                TBODYjacsFootDetail.appendChild(TRjacsFootDetail);

                                    TDjacsFootDetail           = document.createElement('td');
                                    TDjacsFootDetail.className = 'jacsClear';
                                    TDjacsFootDetail.id        = calId+'Clear';
                                    TDjacsFootDetail.style.padding = '0px';
                                    TRjacsFootDetail.appendChild(TDjacsFootDetail);

                                        INPUTjacsClearButton           = document.createElement('input');
                                        INPUTjacsClearButton.type      = 'button';
                                        INPUTjacsClearButton.id        = calId+'ClearButton';
                                        INPUTjacsClearButton.className = 'Clear';
                                        INPUTjacsClearButton.style.textAlign = 'center';
                                        INPUTjacsClearButton.onclick   = function() {cal.targetEle.value='';hide(calId);};
                                        TDjacsFootDetail.appendChild(INPUTjacsClearButton);

                                    TDjacsNow                 = document.createElement('td');
                                    TDjacsNow.className       = 'jacsNow';
                                    TDjacsNow.id              = calId+'Now';
                                    TDjacsNow.style.padding   = '0px';
                                    TRjacsFootDetail.appendChild(TDjacsNow);

                 if (TABLEjacs.clickToHide)
                    {if (document.addEventListener)
                            {      TABLEjacs.addEventListener('click',    cancel,         false);
                                   TABLEjacs.addEventListener('change',   cancel,         false);
                                  TDjacsDrag.addEventListener('mousedown',beginDrag,      false);
                              INPUTjacsHead1.addEventListener('click',    stopPropagation,false);
                             SELECTjacsHead2.addEventListener('click',    stopPropagation,false);
                             SELECTjacsHead2.addEventListener('change',   stopPropagation,false);
                             SELECTjacsHead3.addEventListener('click',    stopPropagation,false);
                             SELECTjacsHead3.addEventListener('change',   stopPropagation,false);
                              INPUTjacsHead4.addEventListener('click',    stopPropagation,false);
                              TBODYjacsCells.addEventListener('click',    stopPropagation,false);
                            }
                     else   {      TABLEjacs.attachEvent('onclick',    cancel);
                                   TABLEjacs.attachEvent('onchange',   cancel);
                                  TDjacsDrag.attachEvent('onmousedown',beginDrag);
                              INPUTjacsHead1.attachEvent('onclick',    stopPropagation);
                             SELECTjacsHead2.attachEvent('onclick',    stopPropagation);
                             SELECTjacsHead2.attachEvent('onchange',   stopPropagation);
                             SELECTjacsHead3.attachEvent('onclick',    stopPropagation);
                             SELECTjacsHead3.attachEvent('onchange',   stopPropagation);
                              INPUTjacsHead4.attachEvent('onclick',    stopPropagation);
                              TBODYjacsCells.attachEvent('onclick',    stopPropagation);
                            }
                    }
                 else
                    {if (document.addEventListener)
                        {      TABLEjacs.addEventListener('click',    stopPropagation,false);
                               TABLEjacs.addEventListener('change',   stopPropagation,false);
                              TDjacsDrag.addEventListener('mousedown',beginDrag,      false);
                        }
                     else
                        {      TABLEjacs.attachEvent('onclick',    stopPropagation);
                               TABLEjacs.attachEvent('onchange',   stopPropagation);
                              TDjacsDrag.attachEvent('onmousedown',beginDrag);
                        }
                    }
                 if (dynamic)
                        {iFrame = document.createElement('iframe');

                         iFrame.className    = 'jacs';
                         iFrame.id           = calId+'Iframe';
                         if (getEl('jacsIElt7')) {iFrame.src = '/jacsblank.html';}
                         iFrame.name         = 'jacsIframe';
                         iFrame.frameborder  = '0';
                         iFrame.style.zIndex = TABLEjacs.zIndex;

                         document.body.insertBefore(iFrame, document.body.firstChild);
                         document.body.insertBefore(TABLEjacs, iFrame);
                        }
                 else   {if (!getEl('jacsSpan'+calId)) {document.writeln("<span id='jacsSpan"+calId+"'></span>");}
                         getEl('jacsSpan'+calId).appendChild(TABLEjacs);
                        }
                },

             cals: function ()  {return cals;},
             next: function ()
                {if (typeof arguments[0]=='string')
                        {calID       = arguments[0];
                         inFunc      = arguments[1];
                         argPosition = 2;
                        }
                 else   {calID       = 'jacs';
                         inFunc      = arguments[0];
                         argPosition = 1;
                        }

                 if (getEl(calID))
                    {// Take the arguments to be passed through to the defined function.

                     var args = new Array();

                     for (var i=argPosition;i<arguments.length;i++) {args.push(arguments[i]);}

                     // Pass them through to jacsRunNext

                     newFunc = inFunc.jacsRunNext(args,calID);

                     // If the function has already been set, clear the old
                     // function and set the new one (mostly relevant for dynamic
                     // calendars but refreshing the function for static calendars
                     // caters for dynamic parameters).

                     var cal = getEl(calID);

                     if (cal.dynamic) {cal.arrOnNext.push(newFunc);}
                     else             {cal.onNext = newFunc;}
                    }
                 else
                    {alert('ERROR: Calendar object <<' + calID + '>> does not exist.\n' +
                           'Please check that the calendar object id is correct\n' +
                           'and that JACS.show is called before JACS.next.');
                    }
                },
                setDropYear: function(BaseYear,DropYear) {
                	_bYear = BaseYear;
                	_dYear = DropYear;
                },
                setXBase: function(XBase) {  //added by Lee
                	_xBase = XBase;
                },
                setDay: function(ForwardDay, BackwardDay) { // add by c
                	_fDay = ForwardDay;
                	_bDay = BackwardDay;
                },
                setHostDay: function(HostDate, BackwardDay)
                {
                	var now=new Date();
                	_fDay=(toDate(HostDate).getTime()-new Date(now.getFullYear(),now.getMonth(),now.getDate()).getTime())/86400000;
                	_bDay=BackwardDay;
                },
                disableDays: function(dList)
                {
                	for(var i=0;i<dList.length;_dList.push(toDate(dList[i++])));
                },
                clearDisableDays: function()
                {
                	_dList = [];
                }
            };
    };

// ******************************
// End of Public Function Library
// ******************************************************
// End of Javascript Advanced Calendar Script (JACS) Code
// ******************************************************mc&      aϤaϥC:Oa
$   *    :https://its.bocmacau.com/zh_CN/js/jacs.js necko:classified 1 strongly-framed 1 security-info FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAAAgAAAAAAAAAAAAAAAAAAAAEAMQFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAAAAAQLMIIEBzCCAu+gAwIBAgIJQgAAADph83afMA0GCSqGSIb3DQEBCwUAMFQxGTAXBgNVBAoMEEFPIEthc3BlcnNreSBMYWIxNzA1BgNVBAMMLkthc3BlcnNreSBBbnRpLVZpcnVzIFBlcnNvbmFsIFJvb3QgQ2VydGlmaWNhdGUwHhcNMjEwNzMwMDQ1MjQ3WhcNMjIwNzI5MDQ1MjQ3WjCB6DEdMBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3PAIBAxMCQ04xGDAWBgsrBgEEAYI3PAIBAhMHQmVpamluZzEbMBkGA1UEBRMSOTExMDAwMDAxMDAwMDEzNDI4MQswCQYDVQQGEwJNTzEOMAwGA1UEBxMFTWFjYXUxHjAcBgNVBAoTFUJBTksgT0YgQ0hJTkEgTElNSVRFRDEjMCEGA1UECxMaQmFuayBvZiBDaGluYSBNYWNhdSBCcmFuY2gxGTAXBgNVBAMTEGl0cy5ib2NtYWNhdS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8Mbk8JZSuoaLjhwGA7u2079onKiOJBCjF6kgrEiSsd9GABl/+73JiWlNw3OHGCS+9PdclqxmCIFo2IPihM9jDuC8cLLH9vdeyrDY6KCtg6Z9xxh9lP2RoJAfKpe5LUSNnIK+kMXIlgyE5hMhr+incWULABH9Zt/31DV+hQg7uQxQE0kTp2egLc2a0of/EPmG53MWqBgLo+QVw2Cv0Y863h7PipDUpdB4hsjszsYHpIfewb4w06qXyjGbFR7+mR1fC6j5QJ7qUMHaWo5qX+Fytmkyw3V/8OiiIkCMM5GRyoOFzphIiip1i/O37qarbD2/SDxlPJ8T5YvZgCAN4orrzAgMBAAGjRzBFMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIFoDAhBgNVHREEGjAYhwTKrzgKghBpdHMuYm9jbWFjYXUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAwQ9R2vvWF9vGl9y/4DdUTMDdqBJXCmd3hqExATR1xEQgo6cZM+Kg9c3fdiY7ZJUvNwzKb+Ne3wtS4YUN6O4oXOwEJnoES5M6GnLJwgvPKX7uth83VIxUId7UoPPxlvioHZN2C9qsz2WH5ZXuMMFJiYyhCYe0l6NiFnqc3y+mCwDJY2bNYT65EZlCFZjJrOODFk9bja4wxnEqO2/qwxKLL/MSCHa3pOTkGWxjQlSkhpkKSJbpcx6jf0SqbKb/Y6KXR8MyM67Tir/h+WK68PMv0VXJIbnWhNuk9ycmuFOATNzCD/Q036hf2glzuFN4J6v+trYNnURMEsVIx9oID0WcdAC8AAwAAAAABAQAAAAAAAARub25lAAAABG5vbmUBlZ+xZWUXSH+rm9iRO+Uxl650zaXNL0c/lvXwt//2LGgAAAACZgoyJpFcT/u7IImFpjLfBb3Dl5pUIkzVhYlpa26W6oMAAAAAAAAECzCCBAcwggLvoAMCAQICCUIAAAA6YfN2nzANBgkqhkiG9w0BAQsFADBUMRkwFwYDVQQKDBBBTyBLYXNwZXJza3kgTGFiMTcwNQYDVQQDDC5LYXNwZXJza3kgQW50aS1WaXJ1cyBQZXJzb25hbCBSb290IENlcnRpZmljYXRlMB4XDTIxMDczMDA0NTI0N1oXDTIyMDcyOTA0NTI0N1owgegxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAkNOMRgwFgYLKwYBBAGCNzwCAQITB0JlaWppbmcxGzAZBgNVBAUTEjkxMTAwMDAwMTAwMDAxMzQyODELMAkGA1UEBhMCTU8xDjAMBgNVBAcTBU1hY2F1MR4wHAYDVQQKExVCQU5LIE9GIENISU5BIExJTUlURUQxIzAhBgNVBAsTGkJhbmsgb2YgQ2hpbmEgTWFjYXUgQnJhbmNoMRkwFwYDVQQDExBpdHMuYm9jbWFjYXUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvDG5PCWUrqGi44cBgO7ttO/aJyojiQQoxepIKxIkrHfRgAZf/u9yYlpTcNzhxgkvvT3XJasZgiBaNiD4oTPYw7gvHCyx/b3Xsqw2OigrYOmfccYfZT9kaCQHyqXuS1EjZyCvpDFyJYMhOYTIa/op3FlCwAR/Wbf99Q1foUIO7kMUBNJE6dnoC3NmtKH/xD5hudzFqgYC6PkFcNgr9GPOt4ez4qQ1KXQeIbI7M7GB6SH3sG+MNOql8oxmxUe/pkdXwuo+UCe6lDB2lqOal/hcrZpMsN1f/DooiJAjDORkcqDhc6YSIoqdYvzt+6mq2w9v0g8ZTyfE+WL2YAgDeKK68wIDAQABo0cwRTATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwIQYDVR0RBBowGIcEyq84CoIQaXRzLmJvY21hY2F1LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAMEPUdr71hfbxpfcv+A3VEzA3agSVwpnd4ahMQE0dcREIKOnGTPioPXN33YmO2SVLzcMym/jXt8LUuGFDejuKFzsBCZ6BEuTOhpyycILzyl+7rYfN1SMVCHe1KDz8Zb4qB2TdgvarM9lh+WV7jDBSYmMoQmHtJejYhZ6nN8vpgsAyWNmzWE+uRGZQhWYyazjgxZPW42uMMZxKjtv6sMSiy/zEgh2t6Tk5BlsY0JUpIaZCkiW6XMeo39Eqmym/2Oil0fDMjOu04q/4fliuvDzL9FVySG51oTbpPcnJrhTgEzcwg/0NN+oX9oJc7hTeCer/ra2DZ1ETBLFSMfaCA9FnHWYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAA5swggOXMIICf6ADAgECAglBAAAAAWHYcyAwDQYJKoZIhvcNAQELBQAwVDEZMBcGA1UECgwQQU8gS2FzcGVyc2t5IExhYjE3MDUGA1UEAwwuS2FzcGVyc2t5IEFudGktVmlydXMgUGVyc29uYWwgUm9vdCBDZXJ0aWZpY2F0ZTAeFw0xMjAxMTAxNzA2NDBaFw0zMjAxMDUxNzA2NDBaMFQxGTAXBgNVBAoMEEFPIEthc3BlcnNreSBMYWIxNzA1BgNVBAMMLkthc3BlcnNreSBBbnRpLVZpcnVzIFBlcnNvbmFsIFJvb3QgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8Mbk8JZSuoaLjhwGA7u2079onKiOJBCjF6kgrEiSsd9GABl/+73JiWlNw3OHGCS+9PdclqxmCIFo2IPihM9jDuC8cLLH9vdeyrDY6KCtg6Z9xxh9lP2RoJAfKpe5LUSNnIK+kMXIlgyE5hMhr+incWULABH9Zt/31DV+hQg7uQxQE0kTp2egLc2a0of/EPmG53MWqBgLo+QVw2Cv0Y863h7PipDUpdB4hsjszsYHpIfewb4w06qXyjGbFR7+mR1fC6j5QJ7qUMHaWo5qX+Fytmkyw3V/8OiiIkCMM5GRyoOFzphIiip1i/O37qarbD2/SDxlPJ8T5YvZgCAN4orrzAgMBAAGjbDBqMA8GA1UdEwEB/wQFMAMBAf8wNQYJYIZIAYb4QgENBCgWJns0MThFOUUwMy1EMTAzLTQzQzAtOEQ5QS0yNTUwQjhFQzk0NEV9MAsGA1UdDwQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEArrgujIAvdjlhzGSuU9WhEhyIzUFTIeBFWEb02PmH4j38yahsGX1cbEaozK0FX2XogFMzDQYEuJMcpIECjhEqsnidnzt429nku+VDEBMG9GCpX+jUwn+wSdxkonDZHNpOvfdF21sKoXomQ8ciwiJYf8A1aeavIZRvoti04Q0iRIPQwt+ZrOWUw9nqrbDKe4S4Pg2RaaNxbrO+E9NMdB2Otl56Oi8o8dCjq+RD8ZfdhQ1H3kqWY/egB9NqQNHpMEFD6KVR377o5bG02U19HMpGRseJtfhFW31HwXnSIqOCqksLm1DM0IsLxoF7xPb4g4ZbswmA6RTiT+fu+qpbMuEVsQA= request-method GET response-head HTTP/1.1 200 OK
Date: Fri, 28 Jan 2022 11:12:38 GMT
Last-Modified: Tue, 13 Jun 2017 03:32:12 GMT
ETag: "1ffaa-551cf14c3a700"
Accept-Ranges: bytes
Content-Length: 130986
Content-Type: application/x-javascript
 original-response-headers Date: Fri, 28 Jan 2022 11:12:38 GMT
Last-Modified: Tue, 13 Jun 2017 03:32:12 GMT
ETag: "1ffaa-551cf14c3a700"
Accept-Ranges: bytes
Content-Length: 130986
Keep-Alive: timeout=10, max=500
Connection: Keep-Alive
Content-Type: application/x-javascript
 ctid 2 eTLD1Access 1;0;21925653, uncompressed-len 0 net-response-time-onstart 409 net-response-time-onstop 410  